This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.

##all viruses - target and off target

library(tidyverse)
── Attaching core tidyverse packages ─── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.0.2     ── Conflicts ───────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(ggpubr)
library(tidyplots)

Attaching package: ‘tidyplots’

The following object is masked from ‘package:ggpubr’:

    gene_expression
library(ggthemes)
library(scales)

Attaching package: ‘scales’

The following object is masked from ‘package:purrr’:

    discard

The following object is masked from ‘package:readr’:

    col_factor

Figure 1 - linear model

Read-in data

#Linear model for TE data - separated by virus
#November 2024

#viral read depth
#use bowtie2 data

library(tidyverse)
library(broom)
library(boot)

####read counts/normalised read counts####

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files
#deduplicated and non-deduplicated

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

####read depths####

#import and combine read depth files

depth_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depth_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

Format data


depths_bt_all <- rbind(depth_dedup_bt, depth_nodedup_bt)

depths_reads <- left_join(depths_bt_all, metadata2, by = "Sample_id") |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  ,
  .default = "RNA"
  ))

####linear model for spike in viruses - mean read depth####

depths_reads_sub <- depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  mutate(log_depth = log10(mean_depth)) |>
  mutate(log_viral_load = log10(Viral.load))

#inspect data
hist(depths_reads_sub$mean_depth)
hist(depths_reads_sub$Viral.load)
hist(depths_reads_sub$log_depth)
hist(depths_reads_sub$log_viral_load)

summary(depths_reads_sub$log_depth)
summary(depths_reads_sub$log_viral_load)

model

#all viruses together

lm1 <-
  glm(log_depth ~ log_viral_load * virus,
      data = depths_reads_sub,
      family = "gaussian")

summary(lm1)

glm.diag.plots(lm1)

pred <- predict(lm1, type = "response")

rsq <- function (x, y) {
  cor(x, y) ^ 2
}

rsq(depths_reads_sub$log_depth, pred)

##split by viruses

cols <- c("#4477AA",
          "#66CCEE",
          "#228833",
          "#CCBB44",
          "#EE6677",
          "#AA3377")

facet_names <- c(
  "Human_adenovirus_40" = "Human adenovirus 40",
  "Human_betaherpesvirus" = "Human betaherpesvirus",
  "Human_respiratory_syncytial_virus" = "Human respiratory syncytial virus",
  "Influenza_B_virus" = "Influenza B virus",
  "Mammalian_orthoreovirus3" = "Mammalian orthoreovirus 3",
  "Zika_virus" = "Zika virus"
)

virus <- (unique(depths_reads_sub$virus)) %>%
  rep(., each = 2) %>%
  data.frame()

list_models <- 
  depths_reads_sub |>
  group_split(virus) |>
  map( ~ lm(log_depth ~ log_viral_load, data = .))

lm_tidy <- 
  map(list_models, broom::tidy) %>%
  do.call(rbind.data.frame, .) %>%
  cbind(virus, .) %>%
  rename(virus = ".") %>%
  select(virus, term, estimate) %>%
  pivot_wider(names_from = "term", values_from = "estimate")

lm_summary <- depths_reads_sub |>
  group_by(virus) |>
  summarise(
    Intercept = lm(log_depth ~ log_viral_load)$coefficients[1],
    Coeff_x1 = lm(log_depth ~ log_viral_load)$coefficients[2],
    R2 = summary(lm(log_depth ~ log_viral_load))$r.squared,
    pvalue = summary(lm(log_depth ~ log_viral_load))$coefficients["log_viral_load", 4]
  )

lm_combined <- 
  left_join(lm_tidy, lm_summary, by = "virus")

Make plot

Final plot

#ggsave("figures/compare_spike_ins_atcc/model_readdepth_dedup.png")

ggsave("figures/manuscript_figure_2025/PDF/Figure_1.pdf",
       width = 8,
       height = 5)

ggsave("figures/manuscript_figure_2025/PNG/Figure_1.png",
       width = 8,
       height = 5)

——————–

Figure S1

Read counts

### Read-in data

#ATCC genomes updated version
#October 2024

#viral load vs read count normalised using different methods, comparing deduplicated and non-deduplicated
#use bowtie2 data

####read counts/normalised read counts####

#metadata

metadata <- read.csv("metadata/sampleIDs_TESpikeIn.csv", header = TRUE)

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files
#deduplicated and non-deduplicated

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

#normalise by both raw read count and genome length - should be the same as mean read depth

counts_reads_norm <- counts_reads |>
  mutate(norm_counts1 = matched / QC_reads) |>
  mutate(norm_counts2 = matched / QC_reads / length) |>
  mutate(norm_counts3 = matched / length) |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

Read depths

####read depths####

#import and combine read depth files

depth_dedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv"
  )
Rows: 95 Columns: 12── Column specification ───────────────────────────────────
Delimiter: "\t"
chr (5): virus, Sample_id, Background, mapper, type
dbl (7): Viral load, mean_depth, median_depth, min, max...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
depth_nodedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv"
  )
Rows: 95 Columns: 12── Column specification ───────────────────────────────────
Delimiter: "\t"
chr (5): virus, Sample_id, Background, mapper, type
dbl (7): Viral load, mean_depth, median_depth, min, max...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
depths_bt_all <- rbind(depth_dedup_bt, depth_nodedup_bt)

depths_reads <- 
  depths_bt_all |>
  left_join(metadata2, by = "Sample_id") |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  )) |>
  rename(Viral.load = `Viral load`)

Format data

#change labels in facet plots

facet_names <- c("dedup_TE" = "Deduplicated",
                 "nodedup_TE" = "Non-Deduplicated")

cols <- c("#4477AA",
          "#66CCEE",
          "#228833",
          "#CCBB44",
          "#EE6677",
          "#AA3377")

Make plots


#plot viral read counts (non normalised)

read_count <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(matched),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_linetype_manual(values=c("dotted", "solid")) + 
  ylab("Log (Viral Reads)") +
  xlab("Genome copies") + 
  scale_x_log10(labels = scales::trans_format("log10", scales::label_math()))

read_count_norm1 <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(norm_counts1),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_linetype_manual(values=c("dotted", "solid")) + 
  ylab("Log (viral reads/cleaned reads)") +
  xlab("Genome copies") + 
  scale_x_log10(labels = scales::trans_format("log10", scales::label_math()))

#normalise by raw read count and genome length

read_count_norm2 <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = (Viral.load),
    y = log10(norm_counts2),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_linetype_manual(values=c("dotted", "solid")) + 
  ylab("Log (viral reads/cleaned reads/genome length)") +
  xlab("Genome copies") + 
  scale_x_log10(labels = scales::trans_format("log10", scales::label_math()))


read_depths <- 
  depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(mean_depth),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 0, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
<<<<<<< HEAD
Error: unexpected input in:
"  ) +
<<"

Final plot

——————–

Figure S2

Read-in data / Make plots

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import and combine read count files
#deduplicated and non-deduplicated

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_bt_all <- rbind(counts_dedup_bt, counts_nodedup_bt)

counts_reads <- left_join(counts_bt_all, metadata2, by = "Sample_id")

#normalise by both raw read count and genome length - should be the same as mean read depth

counts_reads_norm <- counts_reads |>
  mutate(norm_counts1 = matched / QC_reads) |>
  mutate(norm_counts2 = matched / QC_reads / length) |>
  mutate(norm_counts3 = matched / length) |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

####compare library capture pool####

cols3 <- c("#228833", "#AA3377")

facet_names <- c("dedup_TE" = "Deduplicated",
                 "nodedup_TE" = "Non-Deduplicated")

metadata3 <- 
  metadata |>
  select(Sample.ID, Pool.for.sequencing) |>
  rename(Sample_id = Sample.ID) |>
  rename(Pool = Pool.for.sequencing)

counts_pool <- left_join(counts_reads_norm, metadata3, by = "Sample_id")

Make plots


pool_counts_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log10(matched),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (Viral Reads)") + xlab("Genome copies") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2")) + 
  scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5})))
  

# pool_readcounts_norm <- 
#   counts_pool |>
#   filter(Background != "p6") |>
#   filter(Background != "control") |>
#   ggplot(aes(x = virus, y = log10(norm_counts1))) +
#   geom_boxplot() +
#   facet_grid(Pool ~ type) +
#   theme_few() +
#   theme(
#     axis.title.x = element_blank(),
#     # axis.text.x = element_blank(),
#     axis.title.y = element_text(size = 10),
#     panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
#     panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
#   ) +
#   ylab("log10(viral reads/cleaned reads)")

pool_norm1_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log10(matched),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray") 
  ) +
  ylab("Log (viral reads/cleaned reads)") + xlab("Genome copies") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2")) + 
    scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5})))

# pool_readcounts_norm2 <- 
#   counts_pool |>
#   filter(Background != "p6") |>
#   filter(Background != "control") |>
#   ggplot(aes(x = virus, y = log10(norm_counts2))) +
#   geom_boxplot() +
#   facet_grid(Pool ~ type) +
#   theme_few() +
#   theme(
#     axis.title.x = element_blank(),
#     # axis.text.x = element_blank(),
#     axis.title.y = element_text(size = 10),
#     panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
#     panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
#   ) +
#   ylab("log10(viral reads/cleaned reads/genome length)")


pool_norm2_sum <- 
  counts_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log10(matched),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (viral reads/cleaned reads/genome length)") + xlab("Genome copies") +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2")) + 
    scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5})))


#import and combine read depth files

depth_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depth_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depths_bt_all <- rbind(depth_dedup_bt, depth_nodedup_bt)

depths_reads <- 
  left_join(depths_bt_all, metadata2, by = "Sample_id") |>
  mutate(genome_structure = case_when((
    virus == "Human_adenovirus_40" |
      virus == "Human_betaherpesvirus"
  ) ~ "DNA",
  .default = "RNA"
  ))

depths_pool <- left_join(depths_reads, metadata3, by = "Sample_id")

# pool_readdepths <- 
#   depths_pool |>
#   filter(Background != "p6") |>
#   filter(Background != "control") |>
#   ggplot(aes(x = virus, y = log10(mean_depth))) +
#   geom_boxplot() +
#   facet_grid(Pool ~ type) +
#   theme_few() +
#   theme(
#     axis.title.x = element_blank(),
#     axis.text.x = element_text(angle = 45, hjust = 1),
#     axis.title.y = element_text(size = 10),
#     panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
#     panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
#   ) +
#   ylab("Log (mean read depth)")

pool_depths_sum <-
  depths_pool |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = as.character(Viral.load),
    y = log10(mean_depth),
    colour = Pool
  )) +
  geom_boxplot() +
  facet_grid( ~ type, labeller = as_labeller(facet_names)) +
  theme_few() +
  theme(
    # axis.title.x = element_blank(),
    # axis.text.x = element_blank(),
    legend.title = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  ylab("Log (mean read depth)") +
  xlab("Genome copies") + 
  scale_x_discrete(labels = c(bquote(10^{2}), bquote(10^{3}), bquote(10^{5}))) +
  scale_color_manual(values = cols3, labels = c("Pool 1", "Pool 2"))

Final plot

ggarrange(
  pool_counts_sum,
  pool_norm1_sum,
  pool_norm2_sum,
  pool_depths_sum,
  nrow = 2,
  ncol = 2,
  common.legend = TRUE, 
  align = "hv"
)


#ggsave("figures/compare_spike_ins_atcc/pool_compare_viruses_sum.png",width=10,height=7)

ggsave("figures/manuscript_figure_2025/PDF/Figure_S2.pdf",
       width = 12,
       height = 8)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S2.png",
       width = 12,
       height = 8)

——————–

Figure S3


##plots of read counts and viral read counts
#November 2024

#metadata

metadata <-
  read.csv(
    "metadata/sampleIDs_TESpikeIn.csv",
    header = TRUE
  )

metadata2 <- metadata |>
  select(Sample.ID, Number.of.read.pairs..quality.adaptor.trimmed.) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import read count files

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

counts_nodedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

#import viral reads mapped (to calculate proportions)

viral_reads_dedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_dedup_atcc_ref_20241108.csv",
    header = TRUE
  )

viral_reads_nodedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_nodedup_atcc_ref_20241108.csv",
    header = TRUE
  )

cols2 <- c("#BB5566", "#004488")

facet_names <- c("dedup_TE" = "Deduplicated",
                 "nodedup_TE" = "Non-Deduplicated")

reads_metadata_dedup <-
  left_join(counts_dedup_bt, metadata2, by = "Sample_id")

reads_viral_dedup <-
  left_join(reads_metadata_dedup, viral_reads_dedup, by = "Sample_id")

reads_metadata_nodedup <-
  left_join(counts_nodedup_bt, metadata2, by = "Sample_id")

reads_viral_nodedup <-
  left_join(reads_metadata_nodedup, viral_reads_nodedup, by = "Sample_id")

reads_viral_all <- rbind(reads_viral_dedup, reads_viral_nodedup)


reads_plot <- 
  reads_viral_all |>
  group_by(Background, Sample_id, Viral.load, type) |>
  summarise(
    total_reads = (QC_reads * 2),
    viral_reads = total_virus_reads,
    ATCC_reads = sum(matched),
    prop_ATCC = ATCC_reads / total_reads,
    prop_viral = total_virus_reads / total_reads,
    diff = viral_reads - ATCC_reads
  ) |>
  unique()

Make plots

Final plot

——————–

No longer required? Figure S4

Make plots

####read counts/depths split by background####

#change labels in facet plots

facet_names_bg <- c(
  "dedup_TE" = "Deduplicated",
  "nodedup_TE" = "Non-Deduplicated",
  "p2" = "M1",
  "p8" = "M2"
)

#break down by Background x virus

background_counts_reads <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(matched),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels =
      c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
      )
  ) +
  scale_x_log10(labels = scales::label_log10()) +
  ylab("Log (Viral Reads)")

backgrounds_counts_reads_norm <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(norm_counts1),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_bw() +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(label = scales::label_log10()) +
  ylab("Log (viral reads/cleaned reads)")

backgrounds_counts_reads_norm2 <- 
  counts_reads_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(norm_counts2),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(labels = scales::label_log10()) +
  ylab("Log (viral reads/cleaned reads/genome length)")

background_read_depths <- 
  depths_reads |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  ggplot(aes(
    x = Viral.load,
    y = log10(mean_depth),
    colour = virus
  )) +
  geom_point() +
  geom_smooth(aes(group = virus, linetype = genome_structure), se = FALSE) +
  facet_grid(Background ~ type, labeller = as_labeller(facet_names_bg)) +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray"),
    axis.title.y = element_text(size = 10),
    legend.title = element_blank()
  ) +
  scale_color_manual(
    values = cols,
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  ) +
  scale_x_log10(label = scales::label_log10()) +
  ylab("Log (mean read depth)")

Final plot

——————–

——————–

>>> Figure 2: plots of TE experiment data - genome coverage & per site coverage

Read-in data

counts_nodedup_bt <-
  read_tsv(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv"
  )
Rows: 96 Columns: 9── Column specification ───────────────────────────────────
Delimiter: "\t"
chr (5): virus, Sample_id, Background, mapper, type
dbl (4): length, matched, unmatched, Viral load
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Format data

persite_coverage_nodedup <- 
  nodedup_per_site |>
  rename(Viral.load = `Viral load`) |>
  group_by(Sample_id, virus, Viral.load, Background, type) |>
  filter(coverage > 0) |>
  summarise(genome_coverage = n()) |>
  left_join(lengths) |>
  mutate(percent_coverage = genome_coverage / length)
`summarise()` has grouped output by 'Sample_id', 'virus', 'Viral.load', 'Background'. You can override using the `.groups` argument.Joining with `by = join_by(virus)`

Make plots

Final plot

——————–

——————–

Figure S4


persite_both <- rbind(dedup_per_site, nodedup_per_site)

persite_reads <- left_join(persite_both, metadata2, by = "Sample_id")

persite_norm <- persite_reads |>
  mutate(norm_cov = coverage / QC_reads)

coverage_labels3 <-c("100" = "1e+02",
                    "1000" = "1e+03",
                    "100000" = "1e+05",
                    "p2" = "M1",
                    "p8"= "M2")

persite_norm$`Viral load` <- 
  factor(persite_norm$`Viral load`, 
         labels = c("0",
                    "10^{2}", 
                    "10^{3}",
                    "10^{5}"))


persite_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  filter(virus == "Human_respiratory_syncytial_virus") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(x = site, y = coverage, fill = Background)) +
  geom_col() +
  facet_wrap(Viral.load ~ Sample_id, label = label_parsed) +
  ylab("Coverage") +
  ggtitle("Human RSV (deduplicated)") +
  guides(fill = guide_legend(title = "Background")) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols2, labels = c("M1", "M2"))

Final plot

ggsave("figures/manuscript_figure_2025/PDF/Figure_S4.pdf",
       width=15,
       height=10)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S4.png",
       width=15,
       height=10)

——————–

Figure S5

####Final plot


ggsave("figures/manuscript_figure_2025/PDF/Figure_S5.pdf",
       width=15,
       height=10)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S5.png",
       width=15,
       height=10)

——————–

Figure S6

####Final plot


ggsave("figures/manuscript_figure_2025/PDF/Figure_S6.pdf",
       width=15,
       height=10)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S6.png",
       width=15,
       height=10)

——————–

Figure S7

HBV <- 
persite_norm |>
  filter(Background != "p6") |>
  filter(Background != "control") |>
  filter(type == "dedup_TE") |>
  filter(virus == "Human_betaherpesvirus") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(x = site, y = coverage, fill = Background)) +
  geom_col() +
  facet_wrap(Viral.load ~ Sample_id, label = label_parsed) +
  ylab("Coverage") +
  ggtitle("Human Betaherpesvirus (deduplicated)") +
  guides(fill = guide_legend(title = "Background")) +
 theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols2, labels = c("M1", "M2"))

####Final plot


ggsave(plot = HBV, file="figures/manuscript_figure_2025/PDF/Figure_S7.pdf",
       width=15,
       height=10,
       dpi = 600)

ggsave(plot = HBV, file="figures/manuscript_figure_2025/PNG/Figure_S7.png",
       width=15,
       height=10)

——————–

Figure S8

#have to do these differently due to segmentation


FLU_ME1 <- persite_norm |>
  filter(virus == "Influenza_B_virus") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p2") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("Coverage") +
  ggtitle("Influenza B virus (Background M1 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
 theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols4, label = c(expression("10"^"2"), expression("10"^"3"), expression("10"^"5")))

FLU_ME2 <- persite_norm |>
  filter(virus == "Influenza_B_virus") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p2") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("Coverage") +
  ggtitle("Influenza B virus (Background M2 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
 theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols4, label = c(expression("10"^"2"), expression("10"^"3"), expression("10"^"5")))


ggarrange(FLU_ME1, FLU_ME2, ncol = 2, common.legend = TRUE)
Warning: log-10 transformation introduced infinite values.Warning: Removed 3867 rows containing missing values or values
outside the scale range (`geom_col()`).Warning: log-10 transformation introduced infinite values.Warning: Removed 3867 rows containing missing values or values
outside the scale range (`geom_col()`).Warning: log-10 transformation introduced infinite values.Warning: Removed 3867 rows containing missing values or values
outside the scale range (`geom_col()`).

####Final plot


ggsave("figures/manuscript_figure_2025/PDF/Figure_S8.pdf",
       width=20,
       height=12,
       dpi=600)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S8.png",
       width=20,
       height=12)

——————–

Figure S9


REO_ME1 <- 
  persite_norm |>
  filter(virus == "Mammalian_orthoreovirus3") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p2") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("Coverage") +
  ggtitle("Mammalian orthoreovirus 3 (Background M1 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top",
    panel.grid.major = element_line(linewidth = 0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth = 0.1, color = "lightgray")
  ) +
  scale_y_log10() +
  scale_fill_manual(values = cols4,
                    label = c(
                      expression("10" ^ "2"),
                      expression("10" ^ "3"),
                      expression("10" ^ "5")
                    ))

REO_ME2 <- 
  persite_norm |>
  filter(virus == "Mammalian_orthoreovirus3") |>
  filter(type == "dedup_TE") |>
  filter(Background == "p8") |>
  rename(Viral.load = `Viral load`) |>
  ggplot(aes(
    x = site,
    y = coverage,
    fill = as.character(Viral.load)
  )) +
  geom_col() +
  facet_grid(seg ~ Sample_id) +
  ylab("Coverage") +
  ggtitle("Mammalian orthoreovirus 3 (Background M2 deduplicated)") +
  guides(fill = guide_legend(title = "Viral load")) +
  theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.text.x = element_text(angle = 30, hjust = 1),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top",
    panel.grid.major = element_line(linewidth = 0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth = 0.1, color = "lightgray")
  ) + scale_y_log10() +
  scale_fill_manual(values = cols4,
                    label = c(
                      expression("10" ^ "2"),
                      expression("10" ^ "3"),
                      expression("10" ^ "5")
                    ))

ggarrange(REO_ME1, REO_ME2, ncol = 2, common.legend = TRUE)
Warning: log-10 transformation introduced infinite values.Warning: Removed 2181 rows containing missing values or values
outside the scale range (`geom_col()`).Warning: log-10 transformation introduced infinite values.Warning: Removed 2181 rows containing missing values or values
outside the scale range (`geom_col()`).Warning: log-10 transformation introduced infinite values.Warning: Removed 934 rows containing missing values or values
outside the scale range (`geom_col()`).

####Final plot

ggsave("figures/manuscript_figure_2025/PDF/Figure_S9.pdf",
       width=20,
       height=12,
       dpi=600)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S9.png",
       width=20,
       height=12,
       dpi=600)

——————–

>>>> Figure 3: all viruses - target and off target

Read-in data


# read in metadata

metadata <-
  read.csv("metadata/sampleIDs_TESpikeIn.csv", header = TRUE)

metadata2 <-
  metadata |>
  select(
    Sample.ID,
    Background.sample,
    Viral.load,
    Number.of.read.pairs..quality.adaptor.trimmed.
  ) |>
  rename(Sample_id = Sample.ID) |>
  rename(QC_reads = Number.of.read.pairs..quality.adaptor.trimmed.)

#import viral reads mapped (to calculate proportions)

viral_reads_dedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_dedup_atcc_ref_20241108.csv",
    header = TRUE
  )

viral_reads_nodedup <-
  read.csv(
    "data_TE/total_virus_mapped_reads_per_sample_nodedup_atcc_ref_20241108.csv",
    header = TRUE
  )

#import contingency tables

contingency_dedup <-
  read.csv(
    "data_TE/contingency_table_mapped_virus_reads_per_family_genus_sample_dedup_atcc_ref_20241106.csv",
    header = TRUE
  )

contingency_nodedup <-
  read.csv(
    "data_TE/contingency_table_mapped_virus_reads_per_family_genus_sample_nodedup_atcc_ref_20241106.csv",
    header = TRUE
  )

contaminants <-
  c("Betacoronavirus", "Alphainfluenzavirus", "Gammaretrovirus")

Format data


# pivot longer  
dedup_long <-
  contingency_dedup |>
  filter(!genus %in% contaminants) |>
  filter(genus != "NA") |>
  pivot_longer(cols = A:P,
               names_to = "Sample_id",
               values_to = "count") |>
  mutate(
    target = case_when(
      genus == "Cyclovirus" ~ "off_target",
      genus == "Cardiovirus" ~ "off_target",
      genus == "Kobuvirus" ~ "off_target",
      .default = "on_target"
    )
  ) |>
  mutate(genome_structure = case_when((genus == "Mastadenovirus" |
                                         genus == "Cytomegalovirus") ~ "DNA",
                                      .default = "RNA"
  ))

no_dedup_long <- contingency_nodedup |>
  filter(!genus %in% contaminants) |>
  filter(genus != "NA") |>
  pivot_longer(cols = A:P,
               names_to = "Sample_id",
               values_to = "count") |>
  mutate(
    target = case_when(
      genus == "Cyclovirus" ~ "off_target",
      genus == "Cardiovirus" ~ "off_target",
      genus == "Kobuvirus" ~ "off_target",
      .default = "on_target"
    )
  ) |>
  mutate(genome_structure = case_when((genus == "Mastadenovirus" |
                                         genus == "Cytomegalovirus") ~ "DNA",
                                      .default = "RNA"
  ))

metadata_dedup <- left_join(dedup_long, metadata2, by = "Sample_id")

dedup_viral_reads <-
  left_join(metadata_dedup, viral_reads_dedup, by = "Sample_id") |>
  mutate(total_reads = QC_reads * 2) |>
  mutate(prop_total = count / total_reads) |>
  mutate(prop_viral = count / total_virus_reads)

metadata_no_dedup <- left_join(no_dedup_long, metadata2, by = "Sample_id")

nodedup_viral_reads <-
  left_join(metadata_no_dedup, viral_reads_nodedup, by = "Sample_id") |>
  mutate(total_reads = QC_reads * 2) |>
  mutate(prop_total = count / total_reads) |>
  mutate(prop_viral = count / total_virus_reads)

Make plots

Dedup – viral reads, prop all reads, and prop viral reads

Final plot

…………………….

…………………….

—-Genome medicine results—-

Figure S10

Read-in data



####read counts/normalised read counts####

#import and combine read count files

gm_readcount_dedup <-
  read.table(
    "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

gm_readcount_nodedup <-
  read.table(
    "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

gm_counts_all <- rbind(gm_readcount_dedup, gm_readcount_nodedup)

read counts

read depth

#import and combine read depth files

depth_dedup_gm <-
  read.table(
    "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depth_nodedup_gm <-
  read.table(
    "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readdepth_per_sample_and_virus_bowtie2_nodedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

depths_gm_all <- rbind(depth_dedup_gm, depth_nodedup_gm)

——————–

Figure S11

Read-in data

####genome coverage####

unzip(zipfile = "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv.zip", exdir = "data_genome_medicine/")

dedup_per_site <-
  read.table(
    "data_genome_medicine/genome_medicine_TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

file.remove("data_genome_medicine/genome_medicine_TE_sequencing_experiment_readdepth_per_site_sample_and_virus_bowtie2_dedup_atcc_ref.tsv")
[1] TRUE
#View(dedup_per_site)

counts_dedup_bt <-
  read.table(
    "data_TE/TE_sequencing_experiment_readcount_per_sample_and_virus_bowtie2_dedup_atcc_ref.tsv",
    sep = "\t",
    header = TRUE
  )

#add length column from read depth file to per site file

lengths <- 
  counts_dedup_bt |>
  select(virus,length) |>
  distinct()

#calculate genome coverage

coverage <- 
  dedup_per_site |>
  group_by(sample_id, virus, Viral.load, Replicate) |>
  filter(coverage > 0) |>
  summarise(genome_coverage = n()) |>
  left_join(lengths) |>
  mutate(percent_coverage = genome_coverage / length)
`summarise()` has grouped output by 'sample_id', 'virus', 'Viral.load'. You can override using the `.groups` argument.Joining with `by = join_by(virus)`
coverage |>
  filter(Viral.load != 0) |>
  ggplot(aes(x = virus, y = percent_coverage)) +
  geom_boxplot(outlier.shape = NA) +
  geom_point(position = position_dodge(width = .75)) +
  facet_grid( ~ as.character(Viral.load)) +
  theme_bw() +
  theme(axis.title.y = element_text(size = 10)) +
  ylab("Genome coverage") +
  theme_few() +
  theme(
    axis.title.x = element_blank(),
    axis.text.x = element_text(angle = 45, hjust = 1),
    axis.title.y = element_text(size = 15),
    axis.text = element_text(size = 12),
    strip.text = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "top",
    panel.grid.major = element_line(linewidth = 0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth = 0.1, color = "lightgray")
  ) +
  scale_y_continuous(limits = c(0, 1)) +
    scale_x_discrete(
    labels = c(
      "Human adenovirus 40",
      "Human betaherpesvirus",
      "Human respiratory syncytial virus",
      "Influenza B virus",
      "Mammalian orthoreovirus 3",
      "Zika virus"
    )
  )


#ggsave("/Users/laura/Dropbox/glasgow/github/te_ug_rodents/figures/genome_medicine/all_genome_coverage.png",width=14,height=6)

#ggsave("/Users/laura/Dropbox/glasgow/github/te_ug_rodents/figures/manuscript_figures_pdf/FigureS12.pdf",width=20,height=6)

*** Final plot ***

#PDF
ggsave(
  "figures/manuscript_figure_2025/PDF/Figure_S11.pdf",
  width = 14,
  height = 6
)

#PNG
ggsave(
  "figures/manuscript_figure_2025/PNG/Figure_S11.png",
  width = 14,
  height = 6
)

——————–

Figure S12

*** Final plot ***

ggsave("figures/manuscript_figure_2025/PDF/Figure_S12.pdf",
       width=12,
       height=10)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S12.png",
       width=12,
       height=10)

…………………….

—-Kobuvirus / Cardiovirus results—-

Figure S13


kobu_depth <-
  read.table(
    "data_kobuvirus/kobuvirus_TE_polyomics_readdepth_20241007.tsv",
    sep = "\t",
    header = TRUE
  ) %>%
  select(!expt) %>%
  select(!Number.of.paired.end.reads..QT.)

cardio_depth <-
  read.table(
    "data_cardiovirus/cardiovirus_denovo_bowtie2_read_depth_per_sample_dedup.tsv",
    sep = ",",
    header = TRUE
  )

cardio_depth_poly <- 
  read.table(
    "data_cardiovirus/cardiovirus_denovo_bowtie2_readdepth_per_sample_dedup_polyomics.tsv",
    sep = ",",
    header = TRUE
  ) |>
  select(-contig_name) |>
  filter(Background %in% c("S18", "S19", "S43")) |>
  select(-Background) |>
  separate(Sample_id, into = c(NA, NA, "Background"), sep = "-", remove = FALSE)

depth_both <- rbind(kobu_depth, cardio_depth, cardio_depth_poly) |>
  mutate(Viral.load = ifelse(is.na(Viral.load), 0, Viral.load))

depth_both$type <- depth_both$type |>
  case_match("dedup_TE" ~ "dedup",
             "dedup_polyomics" ~ "dedup",
             .default = depth_both$type)

depth_both$Sample_id <- depth_both$Sample_id |>
  case_match("RNA-Msp-p2" ~ "M1",
             "RNA-Msp-p8" ~ "M2",
             "RNA-Msp-p6" ~ "M3",
             .default = depth_both$Sample_id
             )

depth_both$virus <- depth_both$virus |>
  case_match("cardiovirus" ~ "Cardiovirus",
             "k97_19971" ~ "Kobuvirus",
             .default = depth_both$virus
             )

cols2 <- c("#BB5566", "#004488")

coverage_labels <- c(
  "k97_19971" = "Kobuvirus",
  "cardiovirus" = "Cardiovirus",
  "p2" = "M1",
  "p8" = "M2"
)

*** Final plot ***


depth_both$Viral.load <- factor(depth_both$Viral.load, labels = c("Shotgun",
    "10^{2}", 
    "10^{3}", 
    "10^{5}"
    ))


# depth_both |>
#   filter(Background != "p6") |>
#   filter(type == "dedup") |>
#   filter(mapper == "bowtie2") |>
#   filter(Viral.load != "NA") |>
#   ggplot(aes(
#     x = Viral.load,
#     y = (mean_depth),
#     colour = Background
#   )) +
#   geom_point() +
#  theme_few() +
#   theme(
#     axis.title.x = element_text(size = 12),
#     axis.title.y = element_text(size = 12),
#     legend.title = element_blank(),
#     legend.position = "none", 
#     panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
#     panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
#   ) +  
#   facet_grid(Background ~ virus, labeller = as_labeller(coverage_labels)) +
#   scale_color_manual(values = cols2) +
#   ylab("Mean read depth") +
#     xlab("Spike-in viral load (gc/ml)") +
#    scale_x_log10(labels = scales::trans_format("log10",
#                                         scales::label_math())) + 
#   scale_y_log10(labels = scales::trans_format("log10",
#                                         scales::label_math()))

# replotting S13 in similar way to S14
depth_both %>%
  filter(Background != "p6") |>
  filter(type == "dedup") |>
  filter(mapper == "bowtie2") |>
  # filter(Viral.load != "NA") |>
  ggplot(aes(x = Sample_id, y = mean_depth, color = Background)) +
  geom_point() +
  ylab("Mean read depth") +
  xlab("Sample ID") +
  facet_grid(virus ~ Viral.load,
             scales = "free_x",
             label = label_parsed) +
  scale_color_manual(values = cols2, labels = c("M1", "M2")) +
 theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "right", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  )+
  scale_y_log10(labels = scales::trans_format("log10",
                                        scales::label_math()))


ggsave("figures/manuscript_figure_2025/PDF/Figure_S13_v2.pdf",
       width=8,
       height=4)

ggsave("figures/manuscript_figure_2025/PNG/Figure_S13_v2.png",
       width=8,
       height=4)

——————–

Figure S14


kobu_per_site <-
  read.table(
    "data_kobuvirus/kobuvirus_TE_polyomics_readdepth_persite_20241007.tsv",
    sep = "\t",
    header = TRUE
  ) %>%
  select(virus,
         seg,
         site,
         coverage,
         n_sites,
         Sample_id,
         Background,
         Viral.load,
         mapper,
         type)

kobu_per_site$Viral.load <- 
  kobu_per_site$Viral.load %>%
  replace_na(., 0)

kobu_per_site$Sample_id <- kobu_per_site$Sample_id %>%
  case_match("RNA-Msp-p2" ~ "M1",
             "RNA-Msp-p8" ~ "M2",
             .default = kobu_per_site$Sample_id)

kobu_per_site$Background <- kobu_per_site$Background %>%
  case_match("p2" ~ "M1",
             "p8" ~ "M2",
             .default = kobu_per_site$Background)

cardio_per_site <-
  read.table(
    "data_cardiovirus/cardiovirus_denovo_bowtie2_read_depth_per_site_and_sample_dedup.tsv",
    sep = ",",
    header = TRUE
  )

cardio_polyomics_per_site <-
  read.table(
    "data_cardiovirus/cardiovirus_denovo_bowtie2_readdepth_per_site_sample_dedup_polyomics.tsv",
    sep = ",",
    header = TRUE
  ) %>%
  select(!contig_name)

#View(cardio_polyomics_per_site)

cardio_TE_polyomics <-
  full_join(
    cardio_per_site,
    cardio_polyomics_per_site,
    by = c(
      "virus",
      "seg",
      "site",
      "coverage",
      "n_sites",
      "Sample_id",
      "Background",
      "Viral.load",
      "mapper",
      "type"
    )
  )

cardio_TE_polyomics$Viral.load <- cardio_TE_polyomics$Viral.load %>%
  replace_na(., 0)

drops <-
  c(
    "RNA-Msp-p1",
    "RNA-Msp-p3",
    "RNA-Msp-p4",
    "RNA-Msp-p5",
    "RNA-Msp-p6",
    "RNA-Msp-p7",
    "RNA-Msp-p9"
  )

cardio_TE_polyomics <- cardio_TE_polyomics %>%
  filter(!Sample_id %in% drops)

cardio_TE_polyomics$Sample_id <- cardio_TE_polyomics$Sample_id %>%
  case_match("RNA-Msp-p2" ~ "M1",
             "RNA-Msp-p8" ~ "M2",
             .default = cardio_TE_polyomics$Sample_id)

cardio_TE_polyomics$Background <- cardio_TE_polyomics$Background %>%
  case_match("S18" ~ "M1",
             "S43" ~ "M2",
             "p2" ~ "M1",
             "p8" ~ "M2",
             .default = cardio_TE_polyomics$Background)

persite_both <- rbind(kobu_per_site, cardio_TE_polyomics)

persite_both$type <- persite_both$type %>%
  case_match("dedup_TE" ~ "dedup",
             "dedup_polyomics" ~ "dedup",
             .default = persite_both$type)

#TE data only - compare coverage between backgrounds/viral loads

cols2 <- c("#BB5566", "#004488")

coverage_labels <- c(
  "100" = "10^{2}",
  "1000" = "10^{3}",
  "100000" = "10^{5}",
  "0" = "Shotgun",
  "Kobuvirus" = "Kobuvirus",
  "Cardiovirus" = "Cardiovirus"
)

coverage_labels2 <- c(
  "100" = "10^{2}",
  "1000" = "10^{3}",
  "100000" = "10^{5}",
  "0" = "Shotgun",
  "A" = "A",
  "B" = "B",
  "C" = "C",
  "D" = "D",
  "F" = "F",
  "G" = "G",
  "H" = "H",
  "I" = "I",
  "J" = "J",
  "K" = "K",
  "L" = "L",
  "M" = "M",
  "N" = "N",
  "O" = "O",
  "P" = "P",
  "ME_P1" = "M1",
  "ME_P2" = "M2"
)

kobu_coverage <- kobu_per_site %>%
  filter(mapper == "bowtie2") %>%
  filter(type == "dedup") %>%
  filter(Background != "p6") %>%
  group_by(Sample_id, Viral.load, Background) %>%
  filter(coverage > 0) %>%
  summarise(genome_coverage = n()) %>%
  mutate(percent_coverage = genome_coverage / 8467) %>%
  mutate(virus = "Kobuvirus")
`summarise()` has grouped output by 'Sample_id', 'Viral.load'. You can override using the `.groups` argument.
cardio_coverage <- cardio_TE_polyomics %>%
  filter(Background != "p6") %>%
  group_by(Sample_id, Viral.load, Background) %>%
  filter(coverage > 0) %>%
  summarise(genome_coverage = n()) %>%
  mutate(percent_coverage = genome_coverage / 6945) %>%
  mutate(virus = "Cardiovirus")
`summarise()` has grouped output by 'Sample_id', 'Viral.load'. You can override using the `.groups` argument.
coverage_both <- rbind(kobu_coverage, cardio_coverage)

coverage_both$Viral.load <- factor(coverage_both$Viral.load, labels = c("Shotgun",
    "10^{2}", 
    "10^{3}", 
    "10^{5}"
    ))

*** Final plot ***


coverage_both %>%
  ggplot(aes(x = Sample_id, y = percent_coverage, color = Background)) +
  geom_point() +
  ylab("Genome coverage") +
  xlab("Sample ID") +
  facet_grid(virus ~ (Viral.load),
             scales = "free_x",
             label = label_parsed) +
  scale_color_manual(values = cols2, labels = c("M1", "M2")) +
 theme_few() +
  theme(
    axis.title.x = element_text(size = 12),
    axis.title.y = element_text(size = 12),
    legend.title = element_blank(),
    legend.position = "right", 
    panel.grid.major = element_line(linewidth=0.1, color = "gray60"),
    panel.grid.minor = element_line(linewidth=0.1, color = "lightgray")
  ) + 
  scale_y_continuous(limits = c(0, 1))

#PDF
ggsave("figures/manuscript_figure_2025/PDF/Figure_S14.pdf", 
       width = 8, 
       height = 4)

#PNG
ggsave("figures/manuscript_figure_2025/PNG/Figure_S14.png", 
       width = 8, 
       height = 4)

——————–

Figure S15

*** Final plot ***

#PDF
ggsave("figures/manuscript_figure_2025/PDF/Figure_S15.pdf",
       width=12,
       height=7)

#PNG
ggsave("figures/manuscript_figure_2025/Png/Figure_S15.png",
       width=12,
       height=7)

Figure S16

*** Final plot ***


#PDF
ggsave("figures/manuscript_figure_2025/PDF/Figure_S16.pdf",
       width=12,
       height=7)


#PNG
ggsave("figures/manuscript_figure_2025/PNG/Figure_S16.png",
       width=12,
       height=7)
LS0tCnRpdGxlOiAidGFyZ2V0X29mZnRhcmdldCIKb3V0cHV0OiBodG1sX25vdGVib29rCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ21kK1NoaWZ0K0VudGVyKi4gCgpgYGB7cn0KIyNhbGwgdmlydXNlcyAtIHRhcmdldCBhbmQgb2ZmIHRhcmdldAoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KHRpZHlwbG90cykKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShzY2FsZXMpCgpgYGAKCiMjIyBGaWd1cmUgMSAtIGxpbmVhciBtb2RlbAoKIyMjIyBSZWFkLWluIGRhdGEKYGBge3J9CiNMaW5lYXIgbW9kZWwgZm9yIFRFIGRhdGEgLSBzZXBhcmF0ZWQgYnkgdmlydXMKI05vdmVtYmVyIDIwMjQKCiN2aXJhbCByZWFkIGRlcHRoCiN1c2UgYm93dGllMiBkYXRhCgpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShicm9vbSkKbGlicmFyeShib290KQoKIyMjI3JlYWQgY291bnRzL25vcm1hbGlzZWQgcmVhZCBjb3VudHMjIyMjCgojbWV0YWRhdGEKCm1ldGFkYXRhIDwtCiAgcmVhZC5jc3YoCiAgICAibWV0YWRhdGEvc2FtcGxlSURzX1RFU3Bpa2VJbi5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCm1ldGFkYXRhMiA8LSBtZXRhZGF0YSB8PgogIHNlbGVjdChTYW1wbGUuSUQsIE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pIHw+CiAgcmVuYW1lKFNhbXBsZV9pZCA9IFNhbXBsZS5JRCkgfD4KICByZW5hbWUoUUNfcmVhZHMgPSBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKQoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGNvdW50IGZpbGVzCiNkZWR1cGxpY2F0ZWQgYW5kIG5vbi1kZWR1cGxpY2F0ZWQKCmNvdW50c19kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY291bnRzX25vZGVkdXBfYnQgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY291bnRzX2J0X2FsbCA8LSByYmluZChjb3VudHNfZGVkdXBfYnQsIGNvdW50c19ub2RlZHVwX2J0KQoKY291bnRzX3JlYWRzIDwtIGxlZnRfam9pbihjb3VudHNfYnRfYWxsLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgojIyMjcmVhZCBkZXB0aHMjIyMjCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgZGVwdGggZmlsZXMKCmRlcHRoX2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpkZXB0aF9ub2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmBgYAoKIyMjIyBGb3JtYXQgZGF0YQpgYGB7cn0KCmRlcHRoc19idF9hbGwgPC0gcmJpbmQoZGVwdGhfZGVkdXBfYnQsIGRlcHRoX25vZGVkdXBfYnQpCgpkZXB0aHNfcmVhZHMgPC0gbGVmdF9qb2luKGRlcHRoc19idF9hbGwsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAsCiAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgojIyMjbGluZWFyIG1vZGVsIGZvciBzcGlrZSBpbiB2aXJ1c2VzIC0gbWVhbiByZWFkIGRlcHRoIyMjIwoKZGVwdGhzX3JlYWRzX3N1YiA8LSBkZXB0aHNfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIG11dGF0ZShsb2dfZGVwdGggPSBsb2cxMChtZWFuX2RlcHRoKSkgfD4KICBtdXRhdGUobG9nX3ZpcmFsX2xvYWQgPSBsb2cxMChWaXJhbC5sb2FkKSkKCiNpbnNwZWN0IGRhdGEKaGlzdChkZXB0aHNfcmVhZHNfc3ViJG1lYW5fZGVwdGgpCmhpc3QoZGVwdGhzX3JlYWRzX3N1YiRWaXJhbC5sb2FkKQpoaXN0KGRlcHRoc19yZWFkc19zdWIkbG9nX2RlcHRoKQpoaXN0KGRlcHRoc19yZWFkc19zdWIkbG9nX3ZpcmFsX2xvYWQpCgpzdW1tYXJ5KGRlcHRoc19yZWFkc19zdWIkbG9nX2RlcHRoKQpzdW1tYXJ5KGRlcHRoc19yZWFkc19zdWIkbG9nX3ZpcmFsX2xvYWQpCgpgYGAKCiMjIyMgbW9kZWwKYGBge3J9CiNhbGwgdmlydXNlcyB0b2dldGhlcgoKbG0xIDwtCiAgZ2xtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkICogdmlydXMsCiAgICAgIGRhdGEgPSBkZXB0aHNfcmVhZHNfc3ViLAogICAgICBmYW1pbHkgPSAiZ2F1c3NpYW4iKQoKc3VtbWFyeShsbTEpCgpnbG0uZGlhZy5wbG90cyhsbTEpCgpwcmVkIDwtIHByZWRpY3QobG0xLCB0eXBlID0gInJlc3BvbnNlIikKCnJzcSA8LSBmdW5jdGlvbiAoeCwgeSkgewogIGNvcih4LCB5KSBeIDIKfQoKcnNxKGRlcHRoc19yZWFkc19zdWIkbG9nX2RlcHRoLCBwcmVkKQoKIyNzcGxpdCBieSB2aXJ1c2VzCgpjb2xzIDwtIGMoIiM0NDc3QUEiLAogICAgICAgICAgIiM2NkNDRUUiLAogICAgICAgICAgIiMyMjg4MzMiLAogICAgICAgICAgIiNDQ0JCNDQiLAogICAgICAgICAgIiNFRTY2NzciLAogICAgICAgICAgIiNBQTMzNzciKQoKZmFjZXRfbmFtZXMgPC0gYygKICAiSHVtYW5fYWRlbm92aXJ1c180MCIgPSAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgIkh1bWFuX2JldGFoZXJwZXN2aXJ1cyIgPSAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAiSHVtYW5fcmVzcGlyYXRvcnlfc3luY3l0aWFsX3ZpcnVzIiA9ICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICJJbmZsdWVuemFfQl92aXJ1cyIgPSAiSW5mbHVlbnphIEIgdmlydXMiLAogICJNYW1tYWxpYW5fb3J0aG9yZW92aXJ1czMiID0gIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICJaaWthX3ZpcnVzIiA9ICJaaWthIHZpcnVzIgopCgp2aXJ1cyA8LSAodW5pcXVlKGRlcHRoc19yZWFkc19zdWIkdmlydXMpKSAlPiUKICByZXAoLiwgZWFjaCA9IDIpICU+JQogIGRhdGEuZnJhbWUoKQoKbGlzdF9tb2RlbHMgPC0gCiAgZGVwdGhzX3JlYWRzX3N1YiB8PgogIGdyb3VwX3NwbGl0KHZpcnVzKSB8PgogIG1hcCggfiBsbShsb2dfZGVwdGggfiBsb2dfdmlyYWxfbG9hZCwgZGF0YSA9IC4pKQoKbG1fdGlkeSA8LSAKICBtYXAobGlzdF9tb2RlbHMsIGJyb29tOjp0aWR5KSAlPiUKICBkby5jYWxsKHJiaW5kLmRhdGEuZnJhbWUsIC4pICU+JQogIGNiaW5kKHZpcnVzLCAuKSAlPiUKICByZW5hbWUodmlydXMgPSAiLiIpICU+JQogIHNlbGVjdCh2aXJ1cywgdGVybSwgZXN0aW1hdGUpICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAidGVybSIsIHZhbHVlc19mcm9tID0gImVzdGltYXRlIikKCmxtX3N1bW1hcnkgPC0gZGVwdGhzX3JlYWRzX3N1YiB8PgogIGdyb3VwX2J5KHZpcnVzKSB8PgogIHN1bW1hcmlzZSgKICAgIEludGVyY2VwdCA9IGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSRjb2VmZmljaWVudHNbMV0sCiAgICBDb2VmZl94MSA9IGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSRjb2VmZmljaWVudHNbMl0sCiAgICBSMiA9IHN1bW1hcnkobG0obG9nX2RlcHRoIH4gbG9nX3ZpcmFsX2xvYWQpKSRyLnNxdWFyZWQsCiAgICBwdmFsdWUgPSBzdW1tYXJ5KGxtKGxvZ19kZXB0aCB+IGxvZ192aXJhbF9sb2FkKSkkY29lZmZpY2llbnRzWyJsb2dfdmlyYWxfbG9hZCIsIDRdCiAgKQoKbG1fY29tYmluZWQgPC0gCiAgbGVmdF9qb2luKGxtX3RpZHksIGxtX3N1bW1hcnksIGJ5ID0gInZpcnVzIikKCgpgYGAKCiMjIyMgTWFrZSBwbG90CmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQoKZ2dwbG90KCkgKwogIGdlb21fcG9pbnQoZGF0YSA9IGRlcHRoc19yZWFkc19zdWIsCiAgICAgICAgICAgICBtYXBwaW5nID0gYWVzKFZpcmFsLmxvYWQsIG1lYW5fZGVwdGgsIGNvbG9yID0gdmlydXMpKSArCiAgZ2VvbV9hYmxpbmUoZGF0YSA9IGxtX2NvbWJpbmVkLCBhZXMoaW50ZXJjZXB0ID0gYChJbnRlcmNlcHQpYCwgc2xvcGUgPSBsb2dfdmlyYWxfbG9hZCksIGxpbmV0eXBlPSJkb3R0ZWQiKSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBsbV9jb21iaW5lZCwKICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIiwKICAgICAgICAgICAgYWVzKAogICAgICAgICAgICAgIHggPSA2KjEwMDAwLAogICAgICAgICAgICAgIHkgPSAyLAogICAgICAgICAgICAgIGxhYmVsID0gcm91bmQoQ29lZmZfeDEsIGRpZ2l0cyA9IDIpKSwKICAgICAgICAgICAgc2l6ZSA9IDMuNSkgKwogIGdlb21fdGV4dChkYXRhID0gbG1fY29tYmluZWQsCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsCiAgICAgICAgICAgIGFlcyh4ID0gMS41KjEwMDAwLCAKICAgICAgICAgICAgICAgIHkgPSAyLCAKICAgICAgICAgICAgICAgIGxhYmVsID0gIlNsb3BlID0iKSwKICAgICAgICAgICAgc2l6ZSA9IDMuNSkgKwogIGdlb21fdGV4dChkYXRhID0gbG1fY29tYmluZWQsCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsCiAgICAgICAgICAgIGFlcygKICAgICAgICAgICAgICB4ID0gNioxMDAwMCwKICAgICAgICAgICAgICB5ID0gNiwKICAgICAgICAgICAgICBsYWJlbCA9IHJvdW5kKFIyLCBkaWdpdHMgPSAyKSksCiAgICAgICAgICAgIHNpemUgPSAzLjUpICsKICBnZW9tX3RleHQoZGF0YSA9IGxtX2NvbWJpbmVkLAogICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLAogICAgICAgICAgICBhZXMoeCA9IDIqMTAwMDAsIAogICAgICAgICAgICAgICAgeSA9IDYsIAogICAgICAgICAgICAgICAgbGFiZWwgPSAiUjIgPSIpLAogICAgICAgICAgICBzaXplID0gMy41KSArCiAgZmFjZXRfd3JhcCggfiB2aXJ1cywgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkKICApICsKICAgIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArIAogIHlsYWIoIk1lYW4gUmVhZCBEZXB0aCIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29scykgKwogIGd1aWRlcyhjb2xvciA9IEZBTFNFKSArCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgCiAgICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCmBgYAoKIyMjIyBGaW5hbCBwbG90CmBgYHtyfQojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvbW9kZWxfcmVhZGRlcHRoX2RlZHVwLnBuZyIpCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlXzEucGRmIiwKICAgICAgIHdpZHRoID0gOCwKICAgICAgIGhlaWdodCA9IDUpCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlXzEucG5nIiwKICAgICAgIHdpZHRoID0gOCwKICAgICAgIGhlaWdodCA9IDUpCgpgYGAKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIEZpZ3VyZSBTMQoKIyMjIFJlYWQgY291bnRzCmBgYHtyfQojIyMgUmVhZC1pbiBkYXRhCgojQVRDQyBnZW5vbWVzIHVwZGF0ZWQgdmVyc2lvbgojT2N0b2JlciAyMDI0CgojdmlyYWwgbG9hZCB2cyByZWFkIGNvdW50IG5vcm1hbGlzZWQgdXNpbmcgZGlmZmVyZW50IG1ldGhvZHMsIGNvbXBhcmluZyBkZWR1cGxpY2F0ZWQgYW5kIG5vbi1kZWR1cGxpY2F0ZWQKI3VzZSBib3d0aWUyIGRhdGEKCiMjIyNyZWFkIGNvdW50cy9ub3JtYWxpc2VkIHJlYWQgY291bnRzIyMjIwoKI21ldGFkYXRhCgptZXRhZGF0YSA8LSByZWFkLmNzdigibWV0YWRhdGEvc2FtcGxlSURzX1RFU3Bpa2VJbi5jc3YiLCBoZWFkZXIgPSBUUlVFKQoKbWV0YWRhdGEyIDwtIG1ldGFkYXRhIHw+CiAgc2VsZWN0KFNhbXBsZS5JRCwgTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikgfD4KICByZW5hbWUoU2FtcGxlX2lkID0gU2FtcGxlLklEKSB8PgogIHJlbmFtZShRQ19yZWFkcyA9IE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgY291bnQgZmlsZXMKI2RlZHVwbGljYXRlZCBhbmQgbm9uLWRlZHVwbGljYXRlZAoKY291bnRzX2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkY291bnRfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjb3VudHNfbm9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjb3VudHNfYnRfYWxsIDwtIHJiaW5kKGNvdW50c19kZWR1cF9idCwgY291bnRzX25vZGVkdXBfYnQpCgpjb3VudHNfcmVhZHMgPC0gbGVmdF9qb2luKGNvdW50c19idF9hbGwsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikKCiNub3JtYWxpc2UgYnkgYm90aCByYXcgcmVhZCBjb3VudCBhbmQgZ2Vub21lIGxlbmd0aCAtIHNob3VsZCBiZSB0aGUgc2FtZSBhcyBtZWFuIHJlYWQgZGVwdGgKCmNvdW50c19yZWFkc19ub3JtIDwtIGNvdW50c19yZWFkcyB8PgogIG11dGF0ZShub3JtX2NvdW50czEgPSBtYXRjaGVkIC8gUUNfcmVhZHMpIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMiA9IG1hdGNoZWQgLyBRQ19yZWFkcyAvIGxlbmd0aCkgfD4KICBtdXRhdGUobm9ybV9jb3VudHMzID0gbWF0Y2hlZCAvIGxlbmd0aCkgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAuZGVmYXVsdCA9ICJSTkEiCiAgKSkKCmBgYAoKCiMjIyBSZWFkIGRlcHRocwpgYGB7cn0KIyMjI3JlYWQgZGVwdGhzIyMjIwoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGRlcHRoIGZpbGVzCgpkZXB0aF9kZWR1cF9idCA8LQogIHJlYWRfdHN2KAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRkZXB0aF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIKICApCgpkZXB0aF9ub2RlZHVwX2J0IDwtCiAgcmVhZF90c3YoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiCiAgKQoKZGVwdGhzX2J0X2FsbCA8LSByYmluZChkZXB0aF9kZWR1cF9idCwgZGVwdGhfbm9kZWR1cF9idCkKCmRlcHRoc19yZWFkcyA8LSAKICBkZXB0aHNfYnRfYWxsIHw+CiAgbGVmdF9qb2luKG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAuZGVmYXVsdCA9ICJSTkEiCiAgKSkgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkKCmBgYAoKCiMjIyBGb3JtYXQgZGF0YQpgYGB7cn0KI2NoYW5nZSBsYWJlbHMgaW4gZmFjZXQgcGxvdHMKCmZhY2V0X25hbWVzIDwtIGMoImRlZHVwX1RFIiA9ICJEZWR1cGxpY2F0ZWQiLAogICAgICAgICAgICAgICAgICJub2RlZHVwX1RFIiA9ICJOb24tRGVkdXBsaWNhdGVkIikKCmNvbHMgPC0gYygiIzQ0NzdBQSIsCiAgICAgICAgICAiIzY2Q0NFRSIsCiAgICAgICAgICAiIzIyODgzMyIsCiAgICAgICAgICAiI0NDQkI0NCIsCiAgICAgICAgICAiI0VFNjY3NyIsCiAgICAgICAgICAiI0FBMzM3NyIpCmBgYAoKIyMjIE1ha2UgcGxvdHMKYGBge3J9CgojcGxvdCB2aXJhbCByZWFkIGNvdW50cyAobm9uIG5vcm1hbGlzZWQpCgpyZWFkX2NvdW50IDwtIAogIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKG1hdGNoZWQpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJkb3R0ZWQiLCAic29saWQiKSkgKyAKICB5bGFiKCJMb2cgKFZpcmFsIFJlYWRzKSIpICsKICB4bGFiKCJHZW5vbWUgY29waWVzIikgKyAKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCnJlYWRfY291bnRfbm9ybTEgPC0gCiAgY291bnRzX3JlYWRzX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nMTAobm9ybV9jb3VudHMxKSwKICAgIGNvbG91ciA9IHZpcnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gdmlydXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gY29scywKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXM9YygiZG90dGVkIiwgInNvbGlkIikpICsgCiAgeWxhYigiTG9nICh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzKSIpICsKICB4bGFiKCJHZW5vbWUgY29waWVzIikgKyAKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCiNub3JtYWxpc2UgYnkgcmF3IHJlYWQgY291bnQgYW5kIGdlbm9tZSBsZW5ndGgKCnJlYWRfY291bnRfbm9ybTIgPC0gCiAgY291bnRzX3JlYWRzX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IChWaXJhbC5sb2FkKSwKICAgIHkgPSBsb2cxMChub3JtX2NvdW50czIpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJkb3R0ZWQiLCAic29saWQiKSkgKyAKICB5bGFiKCJMb2cgKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMvZ2Vub21lIGxlbmd0aCkiKSArCiAgeGxhYigiR2Vub21lIGNvcGllcyIpICsgCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpCgoKcmVhZF9kZXB0aHMgPC0gCiAgZGVwdGhzX3JlYWRzIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKG1lYW5fZGVwdGgpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCjw8PDw8PDwgSEVBRAogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXM9YygyLCAxKSkgKwo9PT09PT09CiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJkb3R0ZWQiLCAic29saWQiKSkgKyAKPj4+Pj4+PiBmZTM2YWRiICh1cGRhdGUgbm90ZWJvb2spCiAgeWxhYigiTG9nIChtZWFuIHJlYWQgZGVwdGgpIikgKwogIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArIAogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKQoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL21lYW5fZGVwdGgucGRmIix3aWR0aD04LGhlaWdodD02KQoKYGBgCgojIyMgKioqRmluYWwgcGxvdCoqKgpgYGB7ciwgd2FybmluZyA9IEZBTFNFLCBlY2hvID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KCmdnYXJyYW5nZSgKICByZWFkX2NvdW50LAogIHJlYWRfY291bnRfbm9ybTEsCiAgcmVhZF9jb3VudF9ub3JtMiwKICByZWFkX2RlcHRocywKICBucm93ID0gMiwKICBuY29sID0gMiwKICBjb21tb24ubGVnZW5kID0gVFJVRSwKICBhbGlnbiA9ICJodiIKKQoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL2xvZ19yZWFkX2NvdW50X2RlcHRoLnBuZyIsd2lkdGg9MTAsaGVpZ2h0PTcpCgojZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlc19wZGYvRmlndXJlUzEucGRmIix3aWR0aD0xMCxoZWlnaHQ9NykKCiNhcHBhcmVudGx5IG5vcm1hbGlzZWQgcmVhZCBjb3VudCB1c2luZyBtZXRob2QgMiBzaG91bGQgbm90IGFjdHVhbGx5IGJlIHRoZSBzYW1lCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1MxLnBkZiIsCiAgICAgICB3aWR0aCA9IDEyLAogICAgICAgaGVpZ2h0ID0gOCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzEucG5nIiwKICAgICAgIHdpZHRoID0gMTIsCiAgICAgICBoZWlnaHQgPSA4KQoKCmBgYAoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgRmlndXJlIFMyCgojIyMgUmVhZC1pbiBkYXRhIC8gTWFrZSBwbG90cwpgYGB7cn0KI21ldGFkYXRhCgptZXRhZGF0YSA8LQogIHJlYWQuY3N2KAogICAgIm1ldGFkYXRhL3NhbXBsZUlEc19URVNwaWtlSW4uY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgptZXRhZGF0YTIgPC0gbWV0YWRhdGEgfD4KICBzZWxlY3QoU2FtcGxlLklELCBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKSB8PgogIHJlbmFtZShTYW1wbGVfaWQgPSBTYW1wbGUuSUQpIHw+CiAgcmVuYW1lKFFDX3JlYWRzID0gTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikKCiNpbXBvcnQgYW5kIGNvbWJpbmUgcmVhZCBjb3VudCBmaWxlcwojZGVkdXBsaWNhdGVkIGFuZCBub24tZGVkdXBsaWNhdGVkCgpjb3VudHNfZGVkdXBfYnQgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvdW50c19ub2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkY291bnRfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvdW50c19idF9hbGwgPC0gcmJpbmQoY291bnRzX2RlZHVwX2J0LCBjb3VudHNfbm9kZWR1cF9idCkKCmNvdW50c19yZWFkcyA8LSBsZWZ0X2pvaW4oY291bnRzX2J0X2FsbCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKI25vcm1hbGlzZSBieSBib3RoIHJhdyByZWFkIGNvdW50IGFuZCBnZW5vbWUgbGVuZ3RoIC0gc2hvdWxkIGJlIHRoZSBzYW1lIGFzIG1lYW4gcmVhZCBkZXB0aAoKY291bnRzX3JlYWRzX25vcm0gPC0gY291bnRzX3JlYWRzIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMSA9IG1hdGNoZWQgLyBRQ19yZWFkcykgfD4KICBtdXRhdGUobm9ybV9jb3VudHMyID0gbWF0Y2hlZCAvIFFDX3JlYWRzIC8gbGVuZ3RoKSB8PgogIG11dGF0ZShub3JtX2NvdW50czMgPSBtYXRjaGVkIC8gbGVuZ3RoKSB8PgogIG11dGF0ZShnZW5vbWVfc3RydWN0dXJlID0gY2FzZV93aGVuKCgKICAgIHZpcnVzID09ICJIdW1hbl9hZGVub3ZpcnVzXzQwIiB8CiAgICAgIHZpcnVzID09ICJIdW1hbl9iZXRhaGVycGVzdmlydXMiCiAgKSB+ICJETkEiLAogIC5kZWZhdWx0ID0gIlJOQSIKICApKQoKIyMjI2NvbXBhcmUgbGlicmFyeSBjYXB0dXJlIHBvb2wjIyMjCgpjb2xzMyA8LSBjKCIjMjI4ODMzIiwgIiNBQTMzNzciKQoKZmFjZXRfbmFtZXMgPC0gYygiZGVkdXBfVEUiID0gIkRlZHVwbGljYXRlZCIsCiAgICAgICAgICAgICAgICAgIm5vZGVkdXBfVEUiID0gIk5vbi1EZWR1cGxpY2F0ZWQiKQoKbWV0YWRhdGEzIDwtIAogIG1ldGFkYXRhIHw+CiAgc2VsZWN0KFNhbXBsZS5JRCwgUG9vbC5mb3Iuc2VxdWVuY2luZykgfD4KICByZW5hbWUoU2FtcGxlX2lkID0gU2FtcGxlLklEKSB8PgogIHJlbmFtZShQb29sID0gUG9vbC5mb3Iuc2VxdWVuY2luZykKCmNvdW50c19wb29sIDwtIGxlZnRfam9pbihjb3VudHNfcmVhZHNfbm9ybSwgbWV0YWRhdGEzLCBieSA9ICJTYW1wbGVfaWQiKQoKYGBgCgojIyMgTWFrZSBwbG90cwpgYGB7cn0KCnBvb2xfY291bnRzX3N1bSA8LSAKICBjb3VudHNfcG9vbCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLAogICAgeSA9IGxvZzEwKG1hdGNoZWQpLAogICAgY29sb3VyID0gUG9vbAogICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgICMgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICB5bGFiKCJMb2cgKFZpcmFsIFJlYWRzKSIpICsgeGxhYigiR2Vub21lIGNvcGllcyIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczMsIGxhYmVscyA9IGMoIlBvb2wgMSIsICJQb29sIDIiKSkgKyAKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGMoYnF1b3RlKDEwXnsyfSksIGJxdW90ZSgxMF57M30pLCBicXVvdGUoMTBeezV9KSkpCiAgCgojIHBvb2xfcmVhZGNvdW50c19ub3JtIDwtIAojICAgY291bnRzX3Bvb2wgfD4KIyAgIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiMgICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiMgICBnZ3Bsb3QoYWVzKHggPSB2aXJ1cywgeSA9IGxvZzEwKG5vcm1fY291bnRzMSkpKSArCiMgICBnZW9tX2JveHBsb3QoKSArCiMgICBmYWNldF9ncmlkKFBvb2wgfiB0eXBlKSArCiMgICB0aGVtZV9mZXcoKSArCiMgICB0aGVtZSgKIyAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAojICAgICAjIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAojICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKIyAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKIyAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQojICAgKSArCiMgICB5bGFiKCJsb2cxMCh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzKSIpCgpwb29sX25vcm0xX3N1bSA8LSAKICBjb3VudHNfcG9vbCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLAogICAgeSA9IGxvZzEwKG1hdGNoZWQpLAogICAgY29sb3VyID0gUG9vbAogICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgICMgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikgCiAgKSArCiAgeWxhYigiTG9nICh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzKSIpICsgeGxhYigiR2Vub21lIGNvcGllcyIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczMsIGxhYmVscyA9IGMoIlBvb2wgMSIsICJQb29sIDIiKSkgKyAKICAgIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzID0gYyhicXVvdGUoMTBeezJ9KSwgYnF1b3RlKDEwXnszfSksIGJxdW90ZSgxMF57NX0pKSkKCiMgcG9vbF9yZWFkY291bnRzX25vcm0yIDwtIAojICAgY291bnRzX3Bvb2wgfD4KIyAgIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiMgICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiMgICBnZ3Bsb3QoYWVzKHggPSB2aXJ1cywgeSA9IGxvZzEwKG5vcm1fY291bnRzMikpKSArCiMgICBnZW9tX2JveHBsb3QoKSArCiMgICBmYWNldF9ncmlkKFBvb2wgfiB0eXBlKSArCiMgICB0aGVtZV9mZXcoKSArCiMgICB0aGVtZSgKIyAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAojICAgICAjIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAojICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKIyAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKIyAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQojICAgKSArCiMgICB5bGFiKCJsb2cxMCh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzL2dlbm9tZSBsZW5ndGgpIikKCgpwb29sX25vcm0yX3N1bSA8LSAKICBjb3VudHNfcG9vbCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLAogICAgeSA9IGxvZzEwKG1hdGNoZWQpLAogICAgY29sb3VyID0gUG9vbAogICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgICMgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICB5bGFiKCJMb2cgKHZpcmFsIHJlYWRzL2NsZWFuZWQgcmVhZHMvZ2Vub21lIGxlbmd0aCkiKSArIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMzLCBsYWJlbHMgPSBjKCJQb29sIDEiLCAiUG9vbCAyIikpICsgCiAgICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscyA9IGMoYnF1b3RlKDEwXnsyfSksIGJxdW90ZSgxMF57M30pLCBicXVvdGUoMTBeezV9KSkpCgoKI2ltcG9ydCBhbmQgY29tYmluZSByZWFkIGRlcHRoIGZpbGVzCgpkZXB0aF9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKZGVwdGhfbm9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpkZXB0aHNfYnRfYWxsIDwtIHJiaW5kKGRlcHRoX2RlZHVwX2J0LCBkZXB0aF9ub2RlZHVwX2J0KQoKZGVwdGhzX3JlYWRzIDwtIAogIGxlZnRfam9pbihkZXB0aHNfYnRfYWxsLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpIHw+CiAgbXV0YXRlKGdlbm9tZV9zdHJ1Y3R1cmUgPSBjYXNlX3doZW4oKAogICAgdmlydXMgPT0gIkh1bWFuX2FkZW5vdmlydXNfNDAiIHwKICAgICAgdmlydXMgPT0gIkh1bWFuX2JldGFoZXJwZXN2aXJ1cyIKICApIH4gIkROQSIsCiAgLmRlZmF1bHQgPSAiUk5BIgogICkpCgpkZXB0aHNfcG9vbCA8LSBsZWZ0X2pvaW4oZGVwdGhzX3JlYWRzLCBtZXRhZGF0YTMsIGJ5ID0gIlNhbXBsZV9pZCIpCgojIHBvb2xfcmVhZGRlcHRocyA8LSAKIyAgIGRlcHRoc19wb29sIHw+CiMgICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgojICAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgojICAgZ2dwbG90KGFlcyh4ID0gdmlydXMsIHkgPSBsb2cxMChtZWFuX2RlcHRoKSkpICsKIyAgIGdlb21fYm94cGxvdCgpICsKIyAgIGZhY2V0X2dyaWQoUG9vbCB+IHR5cGUpICsKIyAgIHRoZW1lX2ZldygpICsKIyAgIHRoZW1lKAojICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiMgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiMgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAojICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAojICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiMgICApICsKIyAgIHlsYWIoIkxvZyAobWVhbiByZWFkIGRlcHRoKSIpCgpwb29sX2RlcHRoc19zdW0gPC0KICBkZXB0aHNfcG9vbCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLAogICAgeSA9IGxvZzEwKG1lYW5fZGVwdGgpLAogICAgY29sb3VyID0gUG9vbAogICkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgICMgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICB5bGFiKCJMb2cgKG1lYW4gcmVhZCBkZXB0aCkiKSArCiAgeGxhYigiR2Vub21lIGNvcGllcyIpICsgCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHMgPSBjKGJxdW90ZSgxMF57Mn0pLCBicXVvdGUoMTBeezN9KSwgYnF1b3RlKDEwXns1fSkpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMzLCBsYWJlbHMgPSBjKCJQb29sIDEiLCAiUG9vbCAyIikpCgoKYGBgCgojIyMgKioqRmluYWwgcGxvdCoqKgpgYGB7cn0KZ2dhcnJhbmdlKAogIHBvb2xfY291bnRzX3N1bSwKICBwb29sX25vcm0xX3N1bSwKICBwb29sX25vcm0yX3N1bSwKICBwb29sX2RlcHRoc19zdW0sCiAgbnJvdyA9IDIsCiAgbmNvbCA9IDIsCiAgY29tbW9uLmxlZ2VuZCA9IFRSVUUsIAogIGFsaWduID0gImh2IgopCgoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL3Bvb2xfY29tcGFyZV92aXJ1c2VzX3N1bS5wbmciLHdpZHRoPTEwLGhlaWdodD03KQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV9TMi5wZGYiLAogICAgICAgd2lkdGggPSAxMiwKICAgICAgIGhlaWdodCA9IDgpCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlX1MyLnBuZyIsCiAgICAgICB3aWR0aCA9IDEyLAogICAgICAgaGVpZ2h0ID0gOCkKCmBgYAoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBGaWd1cmUgUzMKYGBge3J9CgojI3Bsb3RzIG9mIHJlYWQgY291bnRzIGFuZCB2aXJhbCByZWFkIGNvdW50cwojTm92ZW1iZXIgMjAyNAoKI21ldGFkYXRhCgptZXRhZGF0YSA8LQogIHJlYWQuY3N2KAogICAgIm1ldGFkYXRhL3NhbXBsZUlEc19URVNwaWtlSW4uY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgptZXRhZGF0YTIgPC0gbWV0YWRhdGEgfD4KICBzZWxlY3QoU2FtcGxlLklELCBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKSB8PgogIHJlbmFtZShTYW1wbGVfaWQgPSBTYW1wbGUuSUQpIHw+CiAgcmVuYW1lKFFDX3JlYWRzID0gTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikKCiNpbXBvcnQgcmVhZCBjb3VudCBmaWxlcwoKY291bnRzX2RlZHVwX2J0IDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkY291bnRfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjb3VudHNfbm9kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgojaW1wb3J0IHZpcmFsIHJlYWRzIG1hcHBlZCAodG8gY2FsY3VsYXRlIHByb3BvcnRpb25zKQoKdmlyYWxfcmVhZHNfZGVkdXAgPC0KICByZWFkLmNzdigKICAgICJkYXRhX1RFL3RvdGFsX3ZpcnVzX21hcHBlZF9yZWFkc19wZXJfc2FtcGxlX2RlZHVwX2F0Y2NfcmVmXzIwMjQxMTA4LmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKdmlyYWxfcmVhZHNfbm9kZWR1cCA8LQogIHJlYWQuY3N2KAogICAgImRhdGFfVEUvdG90YWxfdmlydXNfbWFwcGVkX3JlYWRzX3Blcl9zYW1wbGVfbm9kZWR1cF9hdGNjX3JlZl8yMDI0MTEwOC5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvbHMyIDwtIGMoIiNCQjU1NjYiLCAiIzAwNDQ4OCIpCgpmYWNldF9uYW1lcyA8LSBjKCJkZWR1cF9URSIgPSAiRGVkdXBsaWNhdGVkIiwKICAgICAgICAgICAgICAgICAibm9kZWR1cF9URSIgPSAiTm9uLURlZHVwbGljYXRlZCIpCgpyZWFkc19tZXRhZGF0YV9kZWR1cCA8LQogIGxlZnRfam9pbihjb3VudHNfZGVkdXBfYnQsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikKCnJlYWRzX3ZpcmFsX2RlZHVwIDwtCiAgbGVmdF9qb2luKHJlYWRzX21ldGFkYXRhX2RlZHVwLCB2aXJhbF9yZWFkc19kZWR1cCwgYnkgPSAiU2FtcGxlX2lkIikKCnJlYWRzX21ldGFkYXRhX25vZGVkdXAgPC0KICBsZWZ0X2pvaW4oY291bnRzX25vZGVkdXBfYnQsIG1ldGFkYXRhMiwgYnkgPSAiU2FtcGxlX2lkIikKCnJlYWRzX3ZpcmFsX25vZGVkdXAgPC0KICBsZWZ0X2pvaW4ocmVhZHNfbWV0YWRhdGFfbm9kZWR1cCwgdmlyYWxfcmVhZHNfbm9kZWR1cCwgYnkgPSAiU2FtcGxlX2lkIikKCnJlYWRzX3ZpcmFsX2FsbCA8LSByYmluZChyZWFkc192aXJhbF9kZWR1cCwgcmVhZHNfdmlyYWxfbm9kZWR1cCkKCgpyZWFkc19wbG90IDwtIAogIHJlYWRzX3ZpcmFsX2FsbCB8PgogIGdyb3VwX2J5KEJhY2tncm91bmQsIFNhbXBsZV9pZCwgVmlyYWwubG9hZCwgdHlwZSkgfD4KICBzdW1tYXJpc2UoCiAgICB0b3RhbF9yZWFkcyA9IChRQ19yZWFkcyAqIDIpLAogICAgdmlyYWxfcmVhZHMgPSB0b3RhbF92aXJ1c19yZWFkcywKICAgIEFUQ0NfcmVhZHMgPSBzdW0obWF0Y2hlZCksCiAgICBwcm9wX0FUQ0MgPSBBVENDX3JlYWRzIC8gdG90YWxfcmVhZHMsCiAgICBwcm9wX3ZpcmFsID0gdG90YWxfdmlydXNfcmVhZHMgLyB0b3RhbF9yZWFkcywKICAgIGRpZmYgPSB2aXJhbF9yZWFkcyAtIEFUQ0NfcmVhZHMKICApIHw+CiAgdW5pcXVlKCkKCmBgYAoKIyMjIE1ha2UgcGxvdHMKYGBge3IsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9Cgp0b3RhbF9yZWFkcyA8LSAKICByZWFkc19wbG90IHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9ICh0b3RhbF9yZWFkcyksCiAgICBjb2xvdXIgPSBCYWNrZ3JvdW5kCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gQmFja2dyb3VuZCksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXMpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIAogICAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgeGxhYigiR2Vub21lIGNvcGllcyIpICsKICAjIGdndGl0bGUoIkFsbCIpICsKICB5bGFiKCJUb3RhbCBudW1iZXIgb2YgcmVhZHMiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJNMSIsICJNMiIpKQoKdmlyYWxfcmVhZHMgPC0gCiAgcmVhZHNfcGxvdCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gVmlyYWwubG9hZCwKICAgIHkgPSAodmlyYWxfcmVhZHMpLAogICAgY29sb3VyID0gQmFja2dyb3VuZAogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IEJhY2tncm91bmQpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyAKICAgIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArCiAgIyBnZ3RpdGxlKCJWaXJhbCByZWFkcyIpICsKICB5bGFiKCJOdW1iZXIgb2YgdmlyYWwgcmVhZHMiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJNMSIsICJNMiIpKQoKQVRDQ19yZWFkcyA8LSAKICByZWFkc19wbG90IHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IChBVENDX3JlYWRzKSwKICAgIGNvbG91ciA9IEJhY2tncm91bmQKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSBCYWNrZ3JvdW5kKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgCiAgICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyB4bGFiKCJHZW5vbWUgY29waWVzIikgKwogIGdndGl0bGUoIlNwaWtlLWluIFZpcmFsIFJlYWRzIikgKwogIHlsYWIoIlNwaWtlLWluIFZpcmFsIFJlYWRzIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiTTEiLCAiTTIiKSkKCnByb3BfQVRDQyA8LSByZWFkc19wbG90IHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gVmlyYWwubG9hZCwgeSA9IHByb3BfQVRDQywgY29sb3VyID0gQmFja2dyb3VuZCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IEJhY2tncm91bmQpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICAgIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArCiAgZ2d0aXRsZSgiU3Bpa2UtaW4gdmlyYWwgcmVhZHMiKSArCiAgeWxhYigiUHJvcG9ydGlvbiIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIk0xIiwgIk0yIikpCgpwcm9wX3ZpcmFsIDwtIHJlYWRzX3Bsb3QgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKHggPSBWaXJhbC5sb2FkLCB5ID0gcHJvcF92aXJhbCwgY29sb3VyID0gQmFja2dyb3VuZCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IEJhY2tncm91bmQpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArCiAgIyBnZ3RpdGxlKCJWaXJhbCByZWFkcyIpICsKICB5bGFiKCJQcm9wb3J0aW9uIG9mIHZpcmFsIHJlYWRzIikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiTTEiLCAiTTIiKSkgKyBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwxLjApKQoKCiNnZ2FycmFuZ2UodG90YWxfcmVhZHMsdmlyYWxfcmVhZHMsQVRDQ19yZWFkcyxwcm9wX3ZpcmFsLHByb3BfQVRDQyxucm93PTIsbmNvbD0zLGNvbW1vbi5sZWdlbmQgPSBUUlVFKQoKYGBgCgojIyMgKioqRmluYWwgcGxvdCoqKgpgYGB7ciwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KCmdnYXJyYW5nZSh0b3RhbF9yZWFkcywKICAgICAgICAgIHZpcmFsX3JlYWRzLAogICAgICAgICAgcHJvcF92aXJhbCwKICAgICAgICAgIG5yb3cgPSAzLAogICAgICAgICAgY29tbW9uLmxlZ2VuZCA9IFRSVUUsCiAgICAgICAgICBhbGlnbiA9ICJodiIpCgojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvYmFja2dyb3VuZHNfcmVhZHMucG5nIikKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzMucGRmIiwgCiAgICAgICB3aWR0aCA9IDgsCiAgICAgICBoZWlnaHQgPSA4KQoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TMy5wbmciLCAKICAgICAgIHdpZHRoID0gOCwKICAgICAgIGhlaWdodCA9IDgpCgojIyMjY29tcGFyZSBwcm9wb3J0aW9uIHZpcmFsIHJlYWRzIHBlciBwb29sIHdpdGggc2hvdGd1biMjIyMKCiMgbWV0YWRhdGEzIDwtIG1ldGFkYXRhIHw+CiMgICBzZWxlY3QoU2FtcGxlLklELAojICAgICAgICAgIE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4sCiMgICAgICAgICAgUG9vbC5mb3Iuc2VxdWVuY2luZykgfD4KIyAgIHJlbmFtZShTYW1wbGVfaWQgPSBTYW1wbGUuSUQpIHw+CiMgICByZW5hbWUoUUNfcmVhZHMgPSBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKQojIAojIHJlYWRzX3ZpcmFsX2RlZHVwMyA8LQojICAgZnVsbF9qb2luKG1ldGFkYXRhMywgdmlyYWxfcmVhZHNfZGVkdXAsIGJ5ID0gIlNhbXBsZV9pZCIpCiMgCiMgcmVhZHNfdmlyYWxfbm9kZWR1cDMgPC0KIyAgIGZ1bGxfam9pbihtZXRhZGF0YTMsIHZpcmFsX3JlYWRzX25vZGVkdXAsIGJ5ID0gIlNhbXBsZV9pZCIpCiMgCiMgcmVhZHNfdmlyYWxfZGVkdXAzIHw+CiMgICBncm91cF9ieShQb29sLmZvci5zZXF1ZW5jaW5nKSB8PgojICAgc3VtbWFyaXNlKAojICAgICB2aXJhbF9yZWFkcyA9IHN1bSh0b3RhbF92aXJ1c19yZWFkcyksCiMgICAgIHRvdGFsX3JlYWRzID0gc3VtKFFDX3JlYWRzICogMiksCiMgICAgIHByb3BfdmlyYWwgPSB2aXJhbF9yZWFkcyAvIHRvdGFsX3JlYWRzCiMgICApCiMgCiMgcG9seW9taWNzIDwtCiMgICByZWFkLmNzdigKIyAgICAgImRhdGFfcG9seW9taWNzL3RvdGFsX3ZpcnVzX21hcHBlZF9yZWFkc19wZXJfc2FtcGxlX2RlZHVwLmNzdiIKIyAgICkKIyAKIyAjcmVhZCBkYXRhIGZyb20gcG9seW9taWNzX2luZGV4ZXNfc3RlZmFubyBkb2N1bWVudAojIHRvdGFsX3JlYWRzIDwtIGRhdGEuZnJhbWUodG90YWxfcmVhZHMgPSBjKDU5NDI3NjAsIDc3MTQyNzUpKQojIAojIGtlZXBzIDwtIGMoIlJOQS1Nc3AtcDIiLCAiUk5BLU1zcC1wOCIpCiMgCiMgcG9seW9taWNzX3JlYWRfcHJvcCA8LSBwb2x5b21pY3MgfD4KIyAgIGZpbHRlcihTYW1wbGVfaWQgJWluJSBrZWVwcykKIyAKIyBwb2x5b21pY3NfcmVhZF9wcm9wMiA8LSBjYmluZChwb2x5b21pY3NfcmVhZF9wcm9wLCB0b3RhbF9yZWFkcykKIyAKIyBwb2x5b21pY3NfcmVhZF9wcm9wMiB8PgojICAgc3VtbWFyaXNlKHByb3BfdmlyYWwgPSB0b3RhbF92aXJ1c19yZWFkcyAvIHRvdGFsX3JlYWRzKQoKYGBgCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIE5vIGxvbmdlciByZXF1aXJlZD8gRmlndXJlIFM0CgojIyMgTWFrZSBwbG90cwpgYGB7cn0KIyMjI3JlYWQgY291bnRzL2RlcHRocyBzcGxpdCBieSBiYWNrZ3JvdW5kIyMjIwoKI2NoYW5nZSBsYWJlbHMgaW4gZmFjZXQgcGxvdHMKCmZhY2V0X25hbWVzX2JnIDwtIGMoCiAgImRlZHVwX1RFIiA9ICJEZWR1cGxpY2F0ZWQiLAogICJub2RlZHVwX1RFIiA9ICJOb24tRGVkdXBsaWNhdGVkIiwKICAicDIiID0gIk0xIiwKICAicDgiID0gIk0yIgopCgojYnJlYWsgZG93biBieSBCYWNrZ3JvdW5kIHggdmlydXMKCmJhY2tncm91bmRfY291bnRzX3JlYWRzIDwtIAogIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKG1hdGNoZWQpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoQmFja2dyb3VuZCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXNfYmcpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPQogICAgICBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICAgKQogICkgKwogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9sb2cxMCgpKSArCiAgeWxhYigiTG9nIChWaXJhbCBSZWFkcykiKQoKYmFja2dyb3VuZHNfY291bnRzX3JlYWRzX25vcm0gPC0gCiAgY291bnRzX3JlYWRzX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gbG9nMTAobm9ybV9jb3VudHMxKSwKICAgIGNvbG91ciA9IHZpcnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gdmlydXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKEJhY2tncm91bmQgfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzX2JnKSkgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgc2NhbGVfeF9sb2cxMChsYWJlbCA9IHNjYWxlczo6bGFiZWxfbG9nMTAoKSkgKwogIHlsYWIoIkxvZyAodmlyYWwgcmVhZHMvY2xlYW5lZCByZWFkcykiKQoKYmFja2dyb3VuZHNfY291bnRzX3JlYWRzX25vcm0yIDwtIAogIGNvdW50c19yZWFkc19ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKG5vcm1fY291bnRzMiksCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZChCYWNrZ3JvdW5kIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lc19iZykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKAogICAgdmFsdWVzID0gY29scywKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9sb2cxMCgpKSArCiAgeWxhYigiTG9nICh2aXJhbCByZWFkcy9jbGVhbmVkIHJlYWRzL2dlbm9tZSBsZW5ndGgpIikKCmJhY2tncm91bmRfcmVhZF9kZXB0aHMgPC0gCiAgZGVwdGhzX3JlYWRzIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IGxvZzEwKG1lYW5fZGVwdGgpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cywgbGluZXR5cGUgPSBnZW5vbWVfc3RydWN0dXJlKSwgc2UgPSBGQUxTRSkgKwogIGZhY2V0X2dyaWQoQmFja2dyb3VuZCB+IHR5cGUsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoZmFjZXRfbmFtZXNfYmcpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IiksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICBzY2FsZV94X2xvZzEwKGxhYmVsID0gc2NhbGVzOjpsYWJlbF9sb2cxMCgpKSArCiAgeWxhYigiTG9nIChtZWFuIHJlYWQgZGVwdGgpIikKCmBgYAoKIyMjICoqKkZpbmFsIHBsb3QqKiogCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTYsIGZpZy5oZWlnaHQ9OH0KCmdnYXJyYW5nZSgKICBiYWNrZ3JvdW5kX2NvdW50c19yZWFkcywKICBiYWNrZ3JvdW5kc19jb3VudHNfcmVhZHNfbm9ybSwKICBiYWNrZ3JvdW5kc19jb3VudHNfcmVhZHNfbm9ybTIsCiAgYmFja2dyb3VuZF9yZWFkX2RlcHRocywKICBucm93ID0gMiwKICBuY29sID0gMiwKICBjb21tb24ubGVnZW5kID0gVFJVRSwKICBhbGlnbiA9ICJodiIKKQoKI2dnc2F2ZSgiZmlndXJlcy9jb21wYXJlX3NwaWtlX2luc19hdGNjL2JhY2tncm91bmRzX3JlYWRfY291bnRfZGVwdGgucG5nIix3aWR0aD0xMCxoZWlnaHQ9NykKCiNnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVzX3BkZi9GaWd1cmVTNC5wZGYiLHdpZHRoPTEwLGhlaWdodD03KQoKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgPj4+IEZpZ3VyZSAyOiBwbG90cyBvZiBURSBleHBlcmltZW50IGRhdGEgLSBnZW5vbWUgY292ZXJhZ2UgJiBwZXIgc2l0ZSBjb3ZlcmFnZQoKIyMjIFJlYWQtaW4gZGF0YQpgYGB7cn0KCiNwbG90cyBvZiBURSBleHBlcmltZW50IGRhdGEgLSBnZW5vbWUgY292ZXJhZ2UgJiBwZXIgc2l0ZSBjb3ZlcmFnZQojYWxzbyBzZXBhcmF0ZWQgYnkgdmlydXNlcwojQVRDQyBnZW5vbWVzIHVwZGF0ZWQgdmVyc2lvbgojT2N0b2JlciAyMDI0CgojdXNlIGJvd3RpZTIgZGF0YQoKIyMjI2dlbm9tZSBjb3ZlcmFnZSMjIyMKCnVuemlwKHppcGZpbGUgPSAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zaXRlX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YuemlwIiwgZXhkaXIgPSAiZGF0YV9URS8iKQoKdW56aXAoemlwZmlsZSA9ICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2LnppcCIsIGV4ZGlyID0gImRhdGFfVEUvIikKCmRlZHVwX3Blcl9zaXRlIDwtCiAgcmVhZF90c3YoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zaXRlX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiCiAgKQoKCm5vZGVkdXBfcGVyX3NpdGUgPC0KICByZWFkX3RzdigKICAgICJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IgogICkKCmZpbGUucmVtb3ZlKCJkYXRhX1RFL1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIpCgpmaWxlLnJlbW92ZSggImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRkZXB0aF9wZXJfc2l0ZV9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfbm9kZWR1cF9hdGNjX3JlZi50c3YiKQoKI2FkZCBsZW5ndGggY29sdW1uIGZyb20gcmVhZCBkZXB0aCBmaWxlIHRvIHBlciBzaXRlIGZpbGUKCiNtZXRhZGF0YQoKbWV0YWRhdGEgPC0KICByZWFkLmNzdigKICAgICJtZXRhZGF0YS9zYW1wbGVJRHNfVEVTcGlrZUluLmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKbWV0YWRhdGEyIDwtIAogIG1ldGFkYXRhIHw+CiAgc2VsZWN0KFNhbXBsZS5JRCwgTnVtYmVyLm9mLnJlYWQucGFpcnMuLnF1YWxpdHkuYWRhcHRvci50cmltbWVkLikgfD4KICByZW5hbWUoU2FtcGxlX2lkID0gU2FtcGxlLklEKSB8PgogIHJlbmFtZShRQ19yZWFkcyA9IE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4pCgojaW1wb3J0IGFuZCBjb21iaW5lIHJlYWQgY291bnQgZmlsZXMKCiNkZWR1cGxpY2F0ZWQgYW5kIG5vbi1kZWR1cGxpY2F0ZWQKCmNvdW50c19kZWR1cF9idCA8LQogIHJlYWRfdHN2KAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIKICApCgpjb3VudHNfbm9kZWR1cF9idCA8LQogIHJlYWRfdHN2KAogICAgImRhdGFfVEUvVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IgogICkKCmNvdW50c19idF9hbGwgPC0gcmJpbmQoY291bnRzX2RlZHVwX2J0LCBjb3VudHNfbm9kZWR1cF9idCkKCmNvdW50c19yZWFkcyA8LSBsZWZ0X2pvaW4oY291bnRzX2J0X2FsbCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKYGBgCgojIyMgRm9ybWF0IGRhdGEKYGBge3J9CiNub3JtYWxpc2UgYnkgYm90aCByYXcgcmVhZCBjb3VudCBhbmQgZ2Vub21lIGxlbmd0aCAtIHNob3VsZCBiZSB0aGUgc2FtZSBhcyBtZWFuIHJlYWQgZGVwdGgKCmNvdW50c19yZWFkc19ub3JtIDwtIAogIGNvdW50c19yZWFkcyB8PgogIG11dGF0ZShub3JtX2NvdW50czEgPSBtYXRjaGVkIC8gUUNfcmVhZHMpIHw+CiAgbXV0YXRlKG5vcm1fY291bnRzMiA9IG1hdGNoZWQgLyBRQ19yZWFkcyAvIGxlbmd0aCkgfD4KICBtdXRhdGUobm9ybV9jb3VudHMzID0gbWF0Y2hlZCAvIGxlbmd0aCkgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IGNhc2Vfd2hlbigoCiAgICB2aXJ1cyA9PSAiSHVtYW5fYWRlbm92aXJ1c180MCIgfAogICAgICB2aXJ1cyA9PSAiSHVtYW5fYmV0YWhlcnBlc3ZpcnVzIgogICkgfiAiRE5BIiwKICAuZGVmYXVsdCA9ICJSTkEiCiAgKSkKCmxlbmd0aHMgPC0gCiAgY291bnRzX3JlYWRzX25vcm0gfD4KICBzZWxlY3QodmlydXMsIGxlbmd0aCkgfD4KICBkaXN0aW5jdCgpCgojY2FsY3VsYXRlIGdlbm9tZSBjb3ZlcmFnZQoKcGVyc2l0ZV9jb3ZlcmFnZV9kZWR1cCA8LSAKICBkZWR1cF9wZXJfc2l0ZSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdyb3VwX2J5KFNhbXBsZV9pZCwgdmlydXMsIFZpcmFsLmxvYWQsIEJhY2tncm91bmQsIHR5cGUpIHw+CiAgZmlsdGVyKGNvdmVyYWdlID4gMCkgfD4KICBzdW1tYXJpc2UoZ2Vub21lX2NvdmVyYWdlID0gbigpKSB8PgogIGxlZnRfam9pbihsZW5ndGhzKSB8PgogIG11dGF0ZShwZXJjZW50X2NvdmVyYWdlID0gZ2Vub21lX2NvdmVyYWdlIC8gbGVuZ3RoKQoKcGVyc2l0ZV9jb3ZlcmFnZV9ub2RlZHVwIDwtIAogIG5vZGVkdXBfcGVyX3NpdGUgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkgfD4KICBncm91cF9ieShTYW1wbGVfaWQsIHZpcnVzLCBWaXJhbC5sb2FkLCBCYWNrZ3JvdW5kLCB0eXBlKSB8PgogIGZpbHRlcihjb3ZlcmFnZSA+IDApIHw+CiAgc3VtbWFyaXNlKGdlbm9tZV9jb3ZlcmFnZSA9IG4oKSkgfD4KICBsZWZ0X2pvaW4obGVuZ3RocykgfD4KICBtdXRhdGUocGVyY2VudF9jb3ZlcmFnZSA9IGdlbm9tZV9jb3ZlcmFnZSAvIGxlbmd0aCkKCnBlcnNpdGVfY292ZXJhZ2VfYm90aCA8LQogIHJiaW5kKHBlcnNpdGVfY292ZXJhZ2VfZGVkdXAsIAogICAgICAgIHBlcnNpdGVfY292ZXJhZ2Vfbm9kZWR1cCkKCmNvdmVyYWdlX2xhYmVscyA8LSBjKCIwIiA9ICJDb250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgIjEwMCIgPSAiMTBeezJ9IiwKICAgICAgICAgICAgICAgICAgICAgIjEwMDAiID0gIjEwXnszfSIsCiAgICAgICAgICAgICAgICAgICAgICIxMDAwMCIgPSAiMTBeezV9IiwKICAgICAgICAgICAgICAgICAgICAgImRlZHVwX1RFIiA9ICJEZWR1cGxpY2F0ZWQiLAogICAgICAgICAgICAgICAgICAgICAibm9kZWR1cF9URSI9ICJOb24tRGVkdXBsaWNhdGVkIikKCmNvdmVyYWdlX2xhYmVsczIgPC0gYygiMCIgPSAiQ29udHJvbCIsCiAgICAgICAgICAgICAgICAgICAgICAiMTAwIiA9ICIxMF57Mn0iLAogICAgICAgICAgICAgICAgICAgICAgIjEwMDAiID0gIjEwXnszfSIsCiAgICAgICAgICAgICAgICAgICAgICAiMTAwMDAiID0gIjEwXns1fSIpCmBgYAoKIyMjIE1ha2UgcGxvdHMKYGBge3IsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9Nn0KCmNvbHMyIDwtIGMoIiNCQjU1NjYiLAogICAgICAgICAgICIjMDA0NDg4IikKCmNvbHM0IDwtIGMoIiNEREFBMzMiLAogICAgICAgICAgICIjQkI1NTY2IiwKICAgICAgICAgICAiIzAwNDQ4OCIpCgoKcGVyc2l0ZV9jb3ZlcmFnZV9ib3RoJFZpcmFsLmxvYWQgPC0gZmFjdG9yKHBlcnNpdGVfY292ZXJhZ2VfYm90aCRWaXJhbC5sb2FkLCBsYWJlbHMgPSBjKCIwIiwKICAgICIxMF57Mn0iLCAKICAgICIxMF57M30iLCAKICAgICIxMF57NX0iCiAgICApKQoKCiMjYXJlIHRoZSBkZWR1cGxpY2F0ZWQgYW5kIG5vbiBkZWR1cGxpY2F0ZWQgZGF0YXNldHMgaWRlbnRpY2FsPz8KIyNpZiB0aGV5IGFyZSB0aGUgc2FtZSBjYW4gbWF5YmUganVzdCBzaG93IG9uZQojc2hvdyBkZWR1cGxpY2F0ZWQKCnBlcnNpdGVfY292ZXJhZ2VfYm90aCB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gdmlydXMsIHkgPSBwZXJjZW50X2NvdmVyYWdlLCBjb2xvdXIgPSBCYWNrZ3JvdW5kKSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gTkEpICsKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuNzUpKSArCiAgZmFjZXRfZ3JpZCh+YXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpLCBsYWJlbGxlciA9IGxhYmVsX3BhcnNlZCkgKwogIHRoZW1lX2ZldygpICsKICB5bGFiKCJHZW5vbWUgY292ZXJhZ2UiKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJNMSIsICJNMiIpKSArCiAgc2NhbGVfeF9kaXNjcmV0ZSgKICAgIGxhYmVscyA9IGMoCiAgICAgICJIdW1hbiBhZGVub3ZpcnVzIDQwIiwKICAgICAgIkh1bWFuIGJldGFoZXJwZXN2aXJ1cyIsCiAgICAgICJIdW1hbiByZXNwaXJhdG9yeSBzeW5jeXRpYWwgdmlydXMiLAogICAgICAiSW5mbHVlbnphIEIgdmlydXMiLAogICAgICAiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyIsCiAgICAgICJaaWthIHZpcnVzIgogICAgKQogICkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDEpKQoKYGBgCgojIyMgKioqRmluYWwgcGxvdCoqKgpgYGB7ciwgZWNobyA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojZ2dzYXZlKCJmaWd1cmVzL2NvbXBhcmVfc3Bpa2VfaW5zX2F0Y2MvZ2Vub21lX2Nvdl9kZWR1cG9ubHkucG5nIix3aWR0aD0xNSxoZWlnaHQ9NikKCmdnc2F2ZSgKICAiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfMi5wZGYiLAogIHdpZHRoID0gMTUsCiAgaGVpZ2h0ID0gNgopCgpnZ3NhdmUoCiAgImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlXzIucG5nIiwKICB3aWR0aCA9IDE1LAogIGhlaWdodCA9IDYKKQoKCmBgYAoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEZpZ3VyZSBTNApgYGB7cn0KCnBlcnNpdGVfYm90aCA8LSByYmluZChkZWR1cF9wZXJfc2l0ZSwgbm9kZWR1cF9wZXJfc2l0ZSkKCnBlcnNpdGVfcmVhZHMgPC0gbGVmdF9qb2luKHBlcnNpdGVfYm90aCwgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKcGVyc2l0ZV9ub3JtIDwtIHBlcnNpdGVfcmVhZHMgfD4KICBtdXRhdGUobm9ybV9jb3YgPSBjb3ZlcmFnZSAvIFFDX3JlYWRzKQoKY292ZXJhZ2VfbGFiZWxzMyA8LWMoIjEwMCIgPSAiMWUrMDIiLAogICAgICAgICAgICAgICAgICAgICIxMDAwIiA9ICIxZSswMyIsCiAgICAgICAgICAgICAgICAgICAgIjEwMDAwMCIgPSAiMWUrMDUiLAogICAgICAgICAgICAgICAgICAgICJwMiIgPSAiTTEiLAogICAgICAgICAgICAgICAgICAgICJwOCI9ICJNMiIpCgpwZXJzaXRlX25vcm0kYFZpcmFsIGxvYWRgIDwtIAogIGZhY3RvcihwZXJzaXRlX25vcm0kYFZpcmFsIGxvYWRgLCAKICAgICAgICAgbGFiZWxzID0gYygiMCIsCiAgICAgICAgICAgICAgICAgICAgIjEwXnsyfSIsIAogICAgICAgICAgICAgICAgICAgICIxMF57M30iLAogICAgICAgICAgICAgICAgICAgICIxMF57NX0iKSkKCgpwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiSHVtYW5fcmVzcGlyYXRvcnlfc3luY3l0aWFsX3ZpcnVzIikgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkgfD4KICBnZ3Bsb3QoYWVzKHggPSBzaXRlLCB5ID0gY292ZXJhZ2UsIGZpbGwgPSBCYWNrZ3JvdW5kKSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X3dyYXAoVmlyYWwubG9hZCB+IFNhbXBsZV9pZCwgbGFiZWwgPSBsYWJlbF9wYXJzZWQpICsKICB5bGFiKCJDb3ZlcmFnZSIpICsKICBnZ3RpdGxlKCJIdW1hbiBSU1YgKGRlZHVwbGljYXRlZCkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiQmFja2dyb3VuZCIpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIk0xIiwgIk0yIikpCmBgYAoKIyMjIyAqKipGaW5hbCBwbG90KioqCmBgYHtyfQpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1M0LnBkZiIsCiAgICAgICB3aWR0aD0xNSwKICAgICAgIGhlaWdodD0xMCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzQucG5nIiwKICAgICAgIHdpZHRoPTE1LAogICAgICAgaGVpZ2h0PTEwKQpgYGAKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBGaWd1cmUgUzUKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9CgpwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJjb250cm9sIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXBfVEUiKSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiWmlrYV92aXJ1cyIpIHw+CiAgcmVuYW1lKFZpcmFsLmxvYWQgPSBgVmlyYWwgbG9hZGApIHw+CiAgZ2dwbG90KGFlcyh4ID0gc2l0ZSwgeSA9IGNvdmVyYWdlLCBmaWxsID0gQmFja2dyb3VuZCkpICsKICBnZW9tX2NvbCgpICsKICBmYWNldF93cmFwKFZpcmFsLmxvYWQgfiBTYW1wbGVfaWQsIGxhYmVsID0gbGFiZWxfcGFyc2VkKSArCiAgeWxhYigiQ292ZXJhZ2UiKSArCiAgZ2d0aXRsZSgiWmlrYSB2aXJ1cyAoZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJCYWNrZ3JvdW5kIikpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiTTEiLCAiTTIiKSkKCmBgYAoKIyMjIyoqKkZpbmFsIHBsb3QqKioKYGBge3J9CgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1M1LnBkZiIsCiAgICAgICB3aWR0aD0xNSwKICAgICAgIGhlaWdodD0xMCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzUucG5nIiwKICAgICAgIHdpZHRoPTE1LAogICAgICAgaGVpZ2h0PTEwKQoKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgRmlndXJlIFM2CmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFfQoKcGVyc2l0ZV9ub3JtIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gInA2IikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAiY29udHJvbCIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBmaWx0ZXIodmlydXMgPT0gIkh1bWFuX2FkZW5vdmlydXNfNDAiKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdncGxvdChhZXMoeCA9IHNpdGUsIHkgPSBjb3ZlcmFnZSwgZmlsbCA9IEJhY2tncm91bmQpKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfd3JhcChWaXJhbC5sb2FkIH4gU2FtcGxlX2lkLCBsYWJlbCA9IGxhYmVsX3BhcnNlZCkgKwogIHlsYWIoIkNvdmVyYWdlIikgKwogIGdndGl0bGUoIkh1bWFuIEFkZW5vdmlydXMgKGRlZHVwbGljYXRlZCkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiQmFja2dyb3VuZCIpKSArCiB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzMiwgbGFiZWxzID0gYygiTTEiLCAiTTIiKSkKCmBgYAoKIyMjIyoqKkZpbmFsIHBsb3QqKioKYGBge3J9CgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1M2LnBkZiIsCiAgICAgICB3aWR0aD0xNSwKICAgICAgIGhlaWdodD0xMCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzYucG5nIiwKICAgICAgIHdpZHRoPTE1LAogICAgICAgaGVpZ2h0PTEwKQoKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgRmlndXJlIFM3CmBgYHtyfQpIQlYgPC0gCnBlcnNpdGVfbm9ybSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgIT0gImNvbnRyb2wiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZmlsdGVyKHZpcnVzID09ICJIdW1hbl9iZXRhaGVycGVzdmlydXMiKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdncGxvdChhZXMoeCA9IHNpdGUsIHkgPSBjb3ZlcmFnZSwgZmlsbCA9IEJhY2tncm91bmQpKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfd3JhcChWaXJhbC5sb2FkIH4gU2FtcGxlX2lkLCBsYWJlbCA9IGxhYmVsX3BhcnNlZCkgKwogIHlsYWIoIkNvdmVyYWdlIikgKwogIGdndGl0bGUoIkh1bWFuIEJldGFoZXJwZXN2aXJ1cyAoZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJCYWNrZ3JvdW5kIikpICsKIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJNMSIsICJNMiIpKQoKYGBgCgojIyMjKioqRmluYWwgcGxvdCoqKgpgYGB7cn0KCmdnc2F2ZShwbG90ID0gSEJWLCBmaWxlPSJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV9TNy5wZGYiLAogICAgICAgd2lkdGg9MTUsCiAgICAgICBoZWlnaHQ9MTAsCiAgICAgICBkcGkgPSA2MDApCgpnZ3NhdmUocGxvdCA9IEhCViwgZmlsZT0iZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzcucG5nIiwKICAgICAgIHdpZHRoPTE1LAogICAgICAgaGVpZ2h0PTEwKQoKCmBgYAoKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBGaWd1cmUgUzgKYGBge3J9CiNoYXZlIHRvIGRvIHRoZXNlIGRpZmZlcmVudGx5IGR1ZSB0byBzZWdtZW50YXRpb24KCgpGTFVfTUUxIDwtIHBlcnNpdGVfbm9ybSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiSW5mbHVlbnphX0JfdmlydXMiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgPT0gInAyIikgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IHNpdGUsCiAgICB5ID0gY292ZXJhZ2UsCiAgICBmaWxsID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpCiAgKSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X2dyaWQoc2VnIH4gU2FtcGxlX2lkKSArCiAgeWxhYigiQ292ZXJhZ2UiKSArCiAgZ2d0aXRsZSgiSW5mbHVlbnphIEIgdmlydXMgKEJhY2tncm91bmQgTTEgZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJWaXJhbCBsb2FkIikpICsKIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbHM0LCBsYWJlbCA9IGMoZXhwcmVzc2lvbigiMTAiXiIyIiksIGV4cHJlc3Npb24oIjEwIl4iMyIpLCBleHByZXNzaW9uKCIxMCJeIjUiKSkpCgpGTFVfTUUyIDwtIHBlcnNpdGVfbm9ybSB8PgogIGZpbHRlcih2aXJ1cyA9PSAiSW5mbHVlbnphX0JfdmlydXMiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgPT0gInAyIikgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IHNpdGUsCiAgICB5ID0gY292ZXJhZ2UsCiAgICBmaWxsID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpCiAgKSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X2dyaWQoc2VnIH4gU2FtcGxlX2lkKSArCiAgeWxhYigiQ292ZXJhZ2UiKSArCiAgZ2d0aXRsZSgiSW5mbHVlbnphIEIgdmlydXMgKEJhY2tncm91bmQgTTIgZGVkdXBsaWNhdGVkKSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZCh0aXRsZSA9ICJWaXJhbCBsb2FkIikpICsKIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsIAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbHM0LCBsYWJlbCA9IGMoZXhwcmVzc2lvbigiMTAiXiIyIiksIGV4cHJlc3Npb24oIjEwIl4iMyIpLCBleHByZXNzaW9uKCIxMCJeIjUiKSkpCgoKZ2dhcnJhbmdlKEZMVV9NRTEsIEZMVV9NRTIsIG5jb2wgPSAyLCBjb21tb24ubGVnZW5kID0gVFJVRSkKCmBgYAoKIyMjIyoqKkZpbmFsIHBsb3QqKioKYGBge3J9CgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1M4LnBkZiIsCiAgICAgICB3aWR0aD0yMCwKICAgICAgIGhlaWdodD0xMiwKICAgICAgIGRwaT02MDApCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlX1M4LnBuZyIsCiAgICAgICB3aWR0aD0yMCwKICAgICAgIGhlaWdodD0xMikKYGBgCgoKIyMjIC0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgRmlndXJlIFM5CmBgYHtyfQoKUkVPX01FMSA8LSAKICBwZXJzaXRlX25vcm0gfD4KICBmaWx0ZXIodmlydXMgPT0gIk1hbW1hbGlhbl9vcnRob3Jlb3ZpcnVzMyIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwX1RFIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCA9PSAicDIiKSB8PgogIHJlbmFtZShWaXJhbC5sb2FkID0gYFZpcmFsIGxvYWRgKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gc2l0ZSwKICAgIHkgPSBjb3ZlcmFnZSwKICAgIGZpbGwgPSBhcy5jaGFyYWN0ZXIoVmlyYWwubG9hZCkKICApKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfZ3JpZChzZWcgfiBTYW1wbGVfaWQpICsKICB5bGFiKCJDb3ZlcmFnZSIpICsKICBnZ3RpdGxlKCJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIChCYWNrZ3JvdW5kIE0xIGRlZHVwbGljYXRlZCkiKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiVmlyYWwgbG9hZCIpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3lfbG9nMTAoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sczQsCiAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSBjKAogICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbigiMTAiIF4gIjIiKSwKICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24oIjEwIiBeICIzIiksCiAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uKCIxMCIgXiAiNSIpCiAgICAgICAgICAgICAgICAgICAgKSkKClJFT19NRTIgPC0gCiAgcGVyc2l0ZV9ub3JtIHw+CiAgZmlsdGVyKHZpcnVzID09ICJNYW1tYWxpYW5fb3J0aG9yZW92aXJ1czMiKSB8PgogIGZpbHRlcih0eXBlID09ICJkZWR1cF9URSIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgPT0gInA4IikgfD4KICByZW5hbWUoVmlyYWwubG9hZCA9IGBWaXJhbCBsb2FkYCkgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IHNpdGUsCiAgICB5ID0gY292ZXJhZ2UsCiAgICBmaWxsID0gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpCiAgKSkgKwogIGdlb21fY29sKCkgKwogIGZhY2V0X2dyaWQoc2VnIH4gU2FtcGxlX2lkKSArCiAgeWxhYigiQ292ZXJhZ2UiKSArCiAgZ2d0aXRsZSgiTWFtbWFsaWFuIG9ydGhvcmVvdmlydXMgMyAoQmFja2dyb3VuZCBNMiBkZWR1cGxpY2F0ZWQpIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIlZpcmFsIGxvYWQiKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xzNCwKICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IGMoCiAgICAgICAgICAgICAgICAgICAgICBleHByZXNzaW9uKCIxMCIgXiAiMiIpLAogICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbigiMTAiIF4gIjMiKSwKICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24oIjEwIiBeICI1IikKICAgICAgICAgICAgICAgICAgICApKQoKZ2dhcnJhbmdlKFJFT19NRTEsIFJFT19NRTIsIG5jb2wgPSAyLCBjb21tb24ubGVnZW5kID0gVFJVRSkKCmBgYAoKIyMjIyoqKkZpbmFsIHBsb3QqKioKYGBge3J9Cmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzkucGRmIiwKICAgICAgIHdpZHRoPTIwLAogICAgICAgaGVpZ2h0PTEyLAogICAgICAgZHBpPTYwMCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzkucG5nIiwKICAgICAgIHdpZHRoPTIwLAogICAgICAgaGVpZ2h0PTEyLAogICAgICAgZHBpPTYwMCkKYGBgCgoKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjID4+Pj4gRmlndXJlIDM6IGFsbCB2aXJ1c2VzIC0gdGFyZ2V0IGFuZCBvZmYgdGFyZ2V0CgojIyMgUmVhZC1pbiBkYXRhCmBgYHtyfQoKIyByZWFkIGluIG1ldGFkYXRhCgptZXRhZGF0YSA8LQogIHJlYWQuY3N2KCJtZXRhZGF0YS9zYW1wbGVJRHNfVEVTcGlrZUluLmNzdiIsIGhlYWRlciA9IFRSVUUpCgptZXRhZGF0YTIgPC0KICBtZXRhZGF0YSB8PgogIHNlbGVjdCgKICAgIFNhbXBsZS5JRCwKICAgIEJhY2tncm91bmQuc2FtcGxlLAogICAgVmlyYWwubG9hZCwKICAgIE51bWJlci5vZi5yZWFkLnBhaXJzLi5xdWFsaXR5LmFkYXB0b3IudHJpbW1lZC4KICApIHw+CiAgcmVuYW1lKFNhbXBsZV9pZCA9IFNhbXBsZS5JRCkgfD4KICByZW5hbWUoUUNfcmVhZHMgPSBOdW1iZXIub2YucmVhZC5wYWlycy4ucXVhbGl0eS5hZGFwdG9yLnRyaW1tZWQuKQoKI2ltcG9ydCB2aXJhbCByZWFkcyBtYXBwZWQgKHRvIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucykKCnZpcmFsX3JlYWRzX2RlZHVwIDwtCiAgcmVhZC5jc3YoCiAgICAiZGF0YV9URS90b3RhbF92aXJ1c19tYXBwZWRfcmVhZHNfcGVyX3NhbXBsZV9kZWR1cF9hdGNjX3JlZl8yMDI0MTEwOC5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCnZpcmFsX3JlYWRzX25vZGVkdXAgPC0KICByZWFkLmNzdigKICAgICJkYXRhX1RFL3RvdGFsX3ZpcnVzX21hcHBlZF9yZWFkc19wZXJfc2FtcGxlX25vZGVkdXBfYXRjY19yZWZfMjAyNDExMDguY3N2IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgojaW1wb3J0IGNvbnRpbmdlbmN5IHRhYmxlcwoKY29udGluZ2VuY3lfZGVkdXAgPC0KICByZWFkLmNzdigKICAgICJkYXRhX1RFL2NvbnRpbmdlbmN5X3RhYmxlX21hcHBlZF92aXJ1c19yZWFkc19wZXJfZmFtaWx5X2dlbnVzX3NhbXBsZV9kZWR1cF9hdGNjX3JlZl8yMDI0MTEwNi5jc3YiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmNvbnRpbmdlbmN5X25vZGVkdXAgPC0KICByZWFkLmNzdigKICAgICJkYXRhX1RFL2NvbnRpbmdlbmN5X3RhYmxlX21hcHBlZF92aXJ1c19yZWFkc19wZXJfZmFtaWx5X2dlbnVzX3NhbXBsZV9ub2RlZHVwX2F0Y2NfcmVmXzIwMjQxMTA2LmNzdiIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY29udGFtaW5hbnRzIDwtCiAgYygiQmV0YWNvcm9uYXZpcnVzIiwgIkFscGhhaW5mbHVlbnphdmlydXMiLCAiR2FtbWFyZXRyb3ZpcnVzIikKCmBgYAoKIyMjIEZvcm1hdCBkYXRhCmBgYHtyfQoKIyBwaXZvdCBsb25nZXIgIApkZWR1cF9sb25nIDwtCiAgY29udGluZ2VuY3lfZGVkdXAgfD4KICBmaWx0ZXIoIWdlbnVzICVpbiUgY29udGFtaW5hbnRzKSB8PgogIGZpbHRlcihnZW51cyAhPSAiTkEiKSB8PgogIHBpdm90X2xvbmdlcihjb2xzID0gQTpQLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJTYW1wbGVfaWQiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY291bnQiKSB8PgogIG11dGF0ZSgKICAgIHRhcmdldCA9IGNhc2Vfd2hlbigKICAgICAgZ2VudXMgPT0gIkN5Y2xvdmlydXMiIH4gIm9mZl90YXJnZXQiLAogICAgICBnZW51cyA9PSAiQ2FyZGlvdmlydXMiIH4gIm9mZl90YXJnZXQiLAogICAgICBnZW51cyA9PSAiS29idXZpcnVzIiB+ICJvZmZfdGFyZ2V0IiwKICAgICAgLmRlZmF1bHQgPSAib25fdGFyZ2V0IgogICAgKQogICkgfD4KICBtdXRhdGUoZ2Vub21lX3N0cnVjdHVyZSA9IAogICAgICAgICAgIGNhc2Vfd2hlbigoZ2VudXMgPT0gIk1hc3RhZGVub3ZpcnVzIiB8IAogICAgICAgICAgICAgICAgICAgICAgICBnZW51cyA9PSAiQ3l0b21lZ2Fsb3ZpcnVzIiB8IAogICAgICAgICAgICAgICAgICAgICAgICBnZW51cyA9PSAiQ3ljbG92aXJ1cyIgfiAiRE5BIiksCiAgICAgICAgICAgICAgICAgICAgIC5kZWZhdWx0ID0gIlJOQSIKICApKQoKbm9fZGVkdXBfbG9uZyA8LSBjb250aW5nZW5jeV9ub2RlZHVwIHw+CiAgZmlsdGVyKCFnZW51cyAlaW4lIGNvbnRhbWluYW50cykgfD4KICBmaWx0ZXIoZ2VudXMgIT0gIk5BIikgfD4KICBwaXZvdF9sb25nZXIoY29scyA9IEE6UCwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiU2FtcGxlX2lkIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImNvdW50IikgfD4KICBtdXRhdGUoCiAgICB0YXJnZXQgPSBjYXNlX3doZW4oCiAgICAgIGdlbnVzID09ICJDeWNsb3ZpcnVzIiB+ICJvZmZfdGFyZ2V0IiwKICAgICAgZ2VudXMgPT0gIkNhcmRpb3ZpcnVzIiB+ICJvZmZfdGFyZ2V0IiwKICAgICAgZ2VudXMgPT0gIktvYnV2aXJ1cyIgfiAib2ZmX3RhcmdldCIsCiAgICAgIC5kZWZhdWx0ID0gIm9uX3RhcmdldCIKICAgICkKICApIHw+CiAgbXV0YXRlKGdlbm9tZV9zdHJ1Y3R1cmUgPSAKICAgICAgICAgICBjYXNlX3doZW4oKGdlbnVzID09ICJNYXN0YWRlbm92aXJ1cyIgfCAKICAgICAgICAgICAgICAgICAgICAgICAgZ2VudXMgPT0gIkN5dG9tZWdhbG92aXJ1cyIgfCAKICAgICAgICAgICAgICAgICAgICAgICAgZ2VudXMgPT0gIkN5Y2xvdmlydXMiIH4gIkROQSIpLAogICAgICAgICAgICAgICAgICAgICAuZGVmYXVsdCA9ICJSTkEiCiAgKSkKCm1ldGFkYXRhX2RlZHVwIDwtIGxlZnRfam9pbihkZWR1cF9sb25nLCBtZXRhZGF0YTIsIGJ5ID0gIlNhbXBsZV9pZCIpCgpkZWR1cF92aXJhbF9yZWFkcyA8LQogIGxlZnRfam9pbihtZXRhZGF0YV9kZWR1cCwgdmlyYWxfcmVhZHNfZGVkdXAsIGJ5ID0gIlNhbXBsZV9pZCIpIHw+CiAgbXV0YXRlKHRvdGFsX3JlYWRzID0gUUNfcmVhZHMgKiAyKSB8PgogIG11dGF0ZShwcm9wX3RvdGFsID0gY291bnQgLyB0b3RhbF9yZWFkcykgfD4KICBtdXRhdGUocHJvcF92aXJhbCA9IGNvdW50IC8gdG90YWxfdmlydXNfcmVhZHMpCgptZXRhZGF0YV9ub19kZWR1cCA8LSBsZWZ0X2pvaW4obm9fZGVkdXBfbG9uZywgbWV0YWRhdGEyLCBieSA9ICJTYW1wbGVfaWQiKQoKbm9kZWR1cF92aXJhbF9yZWFkcyA8LQogIGxlZnRfam9pbihtZXRhZGF0YV9ub19kZWR1cCwgdmlyYWxfcmVhZHNfbm9kZWR1cCwgYnkgPSAiU2FtcGxlX2lkIikgfD4KICBtdXRhdGUodG90YWxfcmVhZHMgPSBRQ19yZWFkcyAqIDIpIHw+CiAgbXV0YXRlKHByb3BfdG90YWwgPSBjb3VudCAvIHRvdGFsX3JlYWRzKSB8PgogIG11dGF0ZShwcm9wX3ZpcmFsID0gY291bnQgLyB0b3RhbF92aXJ1c19yZWFkcykKCmBgYAoKIyMjIE1ha2UgcGxvdHMKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9CgpmYWNldF9uYW1lcyA8LSBjKAogICJNc3BfcDIiID0gIk0xIiwKICAiTXNwX3A4IiA9ICJNMiIsCiAgIm9mZl90YXJnZXQiID0gIkJhY2tncm91bmQiLAogICJvbl90YXJnZXQiID0gIlNwaWtlLWluIgopCgpjb2xzIDwtCiAgYygKICAgICIjQ0NCQjQ0IiwKICAgICIjMzMyMjg4IiwKICAgICIjRUU3NzMzIiwKICAgICIjNjZDQ0VFIiwKICAgICIjODgyMjU1IiwKICAgICIjNDQ3N0FBIiwKICAgICIjQUEzMzc3IiwKICAgICIjMjI4ODMzIiwKICAgICIjRUU2Njc3IgogICkKCgpkZWR1cF9yZWFkcyA8LSAKICBkZWR1cF92aXJhbF9yZWFkcyB8PgogIGZpbHRlcihCYWNrZ3JvdW5kLnNhbXBsZSAhPSAiTmVnX2NvbnRyb2wiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kLnNhbXBsZSAhPSAiTXNwX3A2IikgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gKGNvdW50KSwKICAgIGNvbG91ciA9IGdlbnVzCiAgKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZ2VudXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKHRhcmdldCB+IEJhY2tncm91bmQuc2FtcGxlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsgCiAgc2NhbGVfeF9sb2cxMCgpICsKICBzY2FsZV95X2xvZzEwKCkgKwogIHlsYWIoIlZpcmFsIFJlYWRzIikgKyAKICB4bGFiKCJHZW5vbWUgY29waWVzIikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29scykgKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXM9YygiZG90dGVkIiwgInNvbGlkIikpICsgCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgCiAgICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAjIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKQoKZGVkdXBfcHJvcF92aXJhbCA8LQogIGRlZHVwX3ZpcmFsX3JlYWRzIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJOZWdfY29udHJvbCIpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQuc2FtcGxlICE9ICJNc3BfcDYiKSB8PgogIGdncGxvdChhZXMoeCA9IFZpcmFsLmxvYWQsIHkgPSBwcm9wX3ZpcmFsLCBjb2xvdXIgPSBnZW51cykpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IGdlbnVzLCBsaW5ldHlwZSA9IGdlbm9tZV9zdHJ1Y3R1cmUpLCBzZSA9IEZBTFNFKSArCiAgZmFjZXRfZ3JpZCh0YXJnZXQgfiBCYWNrZ3JvdW5kLnNhbXBsZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArIAogIHNjYWxlX3hfbG9nMTAoKSArCiAgc2NhbGVfeV9sb2cxMCgpICsKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcz1jKCJkb3R0ZWQiLCAic29saWQiKSkgKyAKICB5bGFiKCJQcm9wb3J0aW9uIG9mIHZpcmFsIHJlYWRzIikgKwogIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzKSArCiAgICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkKCmRlZHVwX3Byb3BfYWxsIDwtCiAgZGVkdXBfdmlyYWxfcmVhZHMgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk5lZ19jb250cm9sIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZC5zYW1wbGUgIT0gIk1zcF9wNiIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gVmlyYWwubG9hZCwgeSA9IHByb3BfdG90YWwsIGNvbG91ciA9IGdlbnVzKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoYWVzKGdyb3VwID0gZ2VudXMsIGxpbmV0eXBlID0gZ2Vub21lX3N0cnVjdHVyZSksIHNlID0gRkFMU0UpICsKICBmYWNldF9ncmlkKHRhcmdldCB+IEJhY2tncm91bmQuc2FtcGxlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsgCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIAogIHNjYWxlX3lfbG9nMTAobGltaXRzID0gYyg1ZS04LCAxKSwgYnJlYWtzID0gMTAqKihzZXEoLTYsMCwyKSksbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKwogIHNjYWxlX2xpbmV0eXBlX21hbnVhbCh2YWx1ZXM9YygiZG90dGVkIiwgInNvbGlkIikpICsgCiAgeWxhYigiUHJvcG9ydGlvbiBvZiB0b3RhbCByZWFkcyIpICsKICB4bGFiKCJHZW5vbWUgY29waWVzIikgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29scykgKwogICAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICMgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAxKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKQoKCmBgYAoKIyMjIERlZHVwIC0tIHZpcmFsIHJlYWRzLCBwcm9wIGFsbCByZWFkcywgYW5kIHByb3AgdmlyYWwgcmVhZHMKYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0UsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTEyfQoKZ2dhcnJhbmdlKAogIGRlZHVwX3JlYWRzLAogIGRlZHVwX3Byb3BfYWxsLAogIGRlZHVwX3Byb3BfdmlyYWwsCiAgbnJvdyA9IDMsCiAgY29tbW9uLmxlZ2VuZCA9IFRSVUUsCiAgYWxpZ24gPSAiaHYiCikKCmBgYAoKIyMjICoqKkZpbmFsIHBsb3QqKioKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD04fQoKCiMjanVzdCBwbG90IHZpcmFsIHJlYWRzIGFuZCBwcm9wIHZpcmFsCgpnZ2FycmFuZ2UoCiAgZGVkdXBfcmVhZHMsCiAgZGVkdXBfcHJvcF92aXJhbCwKICBucm93ID0gMiwKICBjb21tb24ubGVnZW5kID0gVFJVRSwKICBhbGlnbiA9ICJodiIKKQoKIyBnZ3NhdmUoImZpZ3VyZXMvY29tcGFyZV9zcGlrZV9pbnNfYXRjYy90YXJnZXRfb2ZmdGFyZ2V0X2RlZHVwXzIwMjUtMDEtMDEucG5nIiwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gOCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfMy5wZGYiLCAKICAgICAgIHdpZHRoID0gMTAsIGhlaWdodCA9IDgpCgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QTkcvRmlndXJlXzMucG5nIiwgCiAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4KQpgYGAKIyMjIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4KIyMjIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4KCiMjIyAtLS0tR2Vub21lIG1lZGljaW5lIHJlc3VsdHMtLS0tCiMjIyBGaWd1cmUgUzEwCgojIyMjIFJlYWQtaW4gZGF0YQpgYGB7cn0KCgojIyMjcmVhZCBjb3VudHMvbm9ybWFsaXNlZCByZWFkIGNvdW50cyMjIyMKCiNpbXBvcnQgYW5kIGNvbWJpbmUgcmVhZCBjb3VudCBmaWxlcwoKZ21fcmVhZGNvdW50X2RlZHVwIDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX2dlbm9tZV9tZWRpY2luZS9nZW5vbWVfbWVkaWNpbmVfVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmdtX3JlYWRjb3VudF9ub2RlZHVwIDwtCiAgcmVhZC50YWJsZSgKICAgICJkYXRhX2dlbm9tZV9tZWRpY2luZS9nZW5vbWVfbWVkaWNpbmVfVEVfc2VxdWVuY2luZ19leHBlcmltZW50X3JlYWRjb3VudF9wZXJfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX25vZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKZ21fY291bnRzX2FsbCA8LSByYmluZChnbV9yZWFkY291bnRfZGVkdXAsIGdtX3JlYWRjb3VudF9ub2RlZHVwKQoKYGBgCgojIyMjIHJlYWQgY291bnRzIApgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI25vcm1hbGlzZSBieSBib3RoIHJhdyByZWFkIGNvdW50IGFuZCBnZW5vbWUgbGVuZ3RoIC0gc2hvdWxkIGJlIHRoZSBzYW1lIGFzIG1lYW4gcmVhZCBkZXB0aAoKZmFjZXRfbmFtZXMgPC0gYygiZGVkdXBfR01fVEUiID0gIkRlZHVwbGljYXRlZCIsCiAgICAgICAgICAgICAgICAgIm5vZGVkdXBfR01fVEUiID0gIk5vbi1EZWR1cGxpY2F0ZWQiKQoKY29scyA8LSBjKCIjNDQ3N0FBIiwKICAgICAgICAgICIjNjZDQ0VFIiwKICAgICAgICAgICIjMjI4ODMzIiwKICAgICAgICAgICIjQ0NCQjQ0IiwKICAgICAgICAgICIjRUU2Njc3IiwKICAgICAgICAgICIjQUEzMzc3IikKCmdtX2NvdW50c19ub3JtIDwtIAogIGdtX2NvdW50c19hbGwgfD4KICBtdXRhdGUobm9ybV9jb3VudHMzID0gbWF0Y2hlZCAvIGxlbmd0aCkKCnJlYWRfY291bnRzIDwtIAogIGdtX2NvdW50c19ub3JtIHw+CiAgZmlsdGVyKFZpcmFsLmxvYWQgIT0gMCkgfD4KICBnZ3Bsb3QoYWVzKAogICAgeCA9IFZpcmFsLmxvYWQsCiAgICB5ID0gKG1hdGNoZWQpLAogICAgY29sb3VyID0gdmlydXMKICApKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChhZXMoZ3JvdXAgPSB2aXJ1cyksIHNlID0gRkFMU0UsIHNwYW4gPSAwLjg1KSArCiAgZmFjZXRfZ3JpZCggfiB0eXBlLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGZhY2V0X25hbWVzKSkgKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgIyBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgKICAgIHZhbHVlcyA9IGNvbHMsCiAgICBsYWJlbHMgPSBjKAogICAgICAiSHVtYW4gYWRlbm92aXJ1cyA0MCIsCiAgICAgICJIdW1hbiBiZXRhaGVycGVzdmlydXMiLAogICAgICAiSHVtYW4gcmVzcGlyYXRvcnkgc3luY3l0aWFsIHZpcnVzIiwKICAgICAgIkluZmx1ZW56YSBCIHZpcnVzIiwKICAgICAgIk1hbW1hbGlhbiBvcnRob3Jlb3ZpcnVzIDMiLAogICAgICAiWmlrYSB2aXJ1cyIKICAgICkKICApICsKICB5bGFiKCJWaXJhbCBSZWFkcyIpICsKICB4bGFiKCJHZW5vbWUgY29waWVzIikgKyAKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6OmxhYmVsX21hdGgoKSkpICsgCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKQoKYGBgCgojIyMjIHJlYWQgZGVwdGgKYGBge3J9CiNpbXBvcnQgYW5kIGNvbWJpbmUgcmVhZCBkZXB0aCBmaWxlcwoKZGVwdGhfZGVkdXBfZ20gPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfZ2Vub21lX21lZGljaW5lL2dlbm9tZV9tZWRpY2luZV9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKZGVwdGhfbm9kZWR1cF9nbSA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9nZW5vbWVfbWVkaWNpbmUvZ2Vub21lX21lZGljaW5lX1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9ub2RlZHVwX2F0Y2NfcmVmLnRzdiIsCiAgICBzZXAgPSAiXHQiLAogICAgaGVhZGVyID0gVFJVRQogICkKCmRlcHRoc19nbV9hbGwgPC0gcmJpbmQoZGVwdGhfZGVkdXBfZ20sIGRlcHRoX25vZGVkdXBfZ20pCgpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQoKcmVhZF9kZXB0aHMgPC0gCiAgZGVwdGhzX2dtX2FsbCB8PgogIGZpbHRlcihWaXJhbC5sb2FkICE9IDApIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBWaXJhbC5sb2FkLAogICAgeSA9IG1lYW5fZGVwdGgsCiAgICBjb2xvdXIgPSB2aXJ1cwogICkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKGFlcyhncm91cCA9IHZpcnVzKSwgc2UgPSBGQUxTRSwgc3BhbiA9IDAuOSkgKwogIGZhY2V0X2dyaWQoIH4gdHlwZSwgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihmYWNldF9uYW1lcykpICsKICB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICMgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoCiAgICB2YWx1ZXMgPSBjb2xzLAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKSArCiAgeWxhYigiTWVhbiByZWFkIGRlcHRoIikgKwogIHhsYWIoIkdlbm9tZSBjb3BpZXMiKSArIAogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKyAKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6OmxhYmVsX21hdGgoKSkpCgoKCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpnZ2FycmFuZ2UocmVhZF9jb3VudHMsCiAgICAgICAgICByZWFkX2RlcHRocywKICAgICAgICAgIG5yb3cgPSAyLAogICAgICAgICAgY29tbW9uLmxlZ2VuZCA9IFRSVUUpCgoKI1BERgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1MxMC5wZGYiLCAKICAgICAgIHdpZHRoID0gNywKICAgICAgIGhlaWdodCA9IDcpCgojUE5HCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzEwLnBuZyIsIAogICAgICAgd2lkdGggPSA3LAogICAgICAgaGVpZ2h0ID0gNykKCmBgYAojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBGaWd1cmUgUzExCgojIyMjIFJlYWQtaW4gZGF0YQpgYGB7cn0KIyMjI2dlbm9tZSBjb3ZlcmFnZSMjIyMKCnVuemlwKHppcGZpbGUgPSAiZGF0YV9nZW5vbWVfbWVkaWNpbmUvZ2Vub21lX21lZGljaW5lX1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdi56aXAiLCBleGRpciA9ICJkYXRhX2dlbm9tZV9tZWRpY2luZS8iKQoKZGVkdXBfcGVyX3NpdGUgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfZ2Vub21lX21lZGljaW5lL2dlbm9tZV9tZWRpY2luZV9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGRlcHRoX3Blcl9zaXRlX3NhbXBsZV9hbmRfdmlydXNfYm93dGllMl9kZWR1cF9hdGNjX3JlZi50c3YiLAogICAgc2VwID0gIlx0IiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpmaWxlLnJlbW92ZSgiZGF0YV9nZW5vbWVfbWVkaWNpbmUvZ2Vub21lX21lZGljaW5lX1RFX3NlcXVlbmNpbmdfZXhwZXJpbWVudF9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2FuZF92aXJ1c19ib3d0aWUyX2RlZHVwX2F0Y2NfcmVmLnRzdiIpCgojVmlldyhkZWR1cF9wZXJfc2l0ZSkKCmNvdW50c19kZWR1cF9idCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9URS9URV9zZXF1ZW5jaW5nX2V4cGVyaW1lbnRfcmVhZGNvdW50X3Blcl9zYW1wbGVfYW5kX3ZpcnVzX2Jvd3RpZTJfZGVkdXBfYXRjY19yZWYudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKI2FkZCBsZW5ndGggY29sdW1uIGZyb20gcmVhZCBkZXB0aCBmaWxlIHRvIHBlciBzaXRlIGZpbGUKCmxlbmd0aHMgPC0gCiAgY291bnRzX2RlZHVwX2J0IHw+CiAgc2VsZWN0KHZpcnVzLGxlbmd0aCkgfD4KICBkaXN0aW5jdCgpCgojY2FsY3VsYXRlIGdlbm9tZSBjb3ZlcmFnZQoKY292ZXJhZ2UgPC0gCiAgZGVkdXBfcGVyX3NpdGUgfD4KICBncm91cF9ieShzYW1wbGVfaWQsIHZpcnVzLCBWaXJhbC5sb2FkLCBSZXBsaWNhdGUpIHw+CiAgZmlsdGVyKGNvdmVyYWdlID4gMCkgfD4KICBzdW1tYXJpc2UoZ2Vub21lX2NvdmVyYWdlID0gbigpKSB8PgogIGxlZnRfam9pbihsZW5ndGhzKSB8PgogIG11dGF0ZShwZXJjZW50X2NvdmVyYWdlID0gZ2Vub21lX2NvdmVyYWdlIC8gbGVuZ3RoKQoKY292ZXJhZ2UgfD4KICBmaWx0ZXIoVmlyYWwubG9hZCAhPSAwKSB8PgogIGdncGxvdChhZXMoeCA9IHZpcnVzLCB5ID0gcGVyY2VudF9jb3ZlcmFnZSkpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BKSArCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gLjc1KSkgKwogIGZhY2V0X2dyaWQoIH4gYXMuY2hhcmFjdGVyKFZpcmFsLmxvYWQpKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICB5bGFiKCJHZW5vbWUgY292ZXJhZ2UiKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJncmF5NjAiKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDEpKSArCiAgICBzY2FsZV94X2Rpc2NyZXRlKAogICAgbGFiZWxzID0gYygKICAgICAgIkh1bWFuIGFkZW5vdmlydXMgNDAiLAogICAgICAiSHVtYW4gYmV0YWhlcnBlc3ZpcnVzIiwKICAgICAgIkh1bWFuIHJlc3BpcmF0b3J5IHN5bmN5dGlhbCB2aXJ1cyIsCiAgICAgICJJbmZsdWVuemEgQiB2aXJ1cyIsCiAgICAgICJNYW1tYWxpYW4gb3J0aG9yZW92aXJ1cyAzIiwKICAgICAgIlppa2EgdmlydXMiCiAgICApCiAgKQoKI2dnc2F2ZSgiL1VzZXJzL2xhdXJhL0Ryb3Bib3gvZ2xhc2dvdy9naXRodWIvdGVfdWdfcm9kZW50cy9maWd1cmVzL2dlbm9tZV9tZWRpY2luZS9hbGxfZ2Vub21lX2NvdmVyYWdlLnBuZyIsd2lkdGg9MTQsaGVpZ2h0PTYpCgojZ2dzYXZlKCIvVXNlcnMvbGF1cmEvRHJvcGJveC9nbGFzZ293L2dpdGh1Yi90ZV91Z19yb2RlbnRzL2ZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVzX3BkZi9GaWd1cmVTMTIucGRmIix3aWR0aD0yMCxoZWlnaHQ9NikKYGBgCgojIyMjICoqKiBGaW5hbCBwbG90ICoqKgpgYGB7cn0KI1BERgpnZ3NhdmUoCiAgImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1MxMS5wZGYiLAogIHdpZHRoID0gMTQsCiAgaGVpZ2h0ID0gNgopCgojUE5HCmdnc2F2ZSgKICAiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzExLnBuZyIsCiAgd2lkdGggPSAxNCwKICBoZWlnaHQgPSA2CikKCmBgYAojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBGaWd1cmUgUzEyCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMjcGVyIHNpdGUgcGxvdCBBZFYgb25seSMjIyMKCmRlZHVwX3Blcl9zaXRlIHw+CiAgZmlsdGVyKHZpcnVzID09ICJIdW1hbl9hZGVub3ZpcnVzXzQwIikgfD4KICBmaWx0ZXIoVmlyYWwubG9hZCAhPSAwKSB8PgogIGdncGxvdChhZXMoeD1zaXRlLHk9Y292ZXJhZ2UpKSsKICBnZW9tX2NvbCgpKwogIGZhY2V0X2dyaWQoVmlyYWwubG9hZH5SZXBsaWNhdGUpKwogIHlsYWIoIkNvdmVyYWdlIHBlciBzaXRlIikrCiAgZ2d0aXRsZSgiSHVtYW4gQWRlbm92aXJ1cyAoZGVkdXBsaWNhdGVkKSIpKwogIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgICMgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAjICMgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSwKICAgICMgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICAjIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICMgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsgIAogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkgKwoKICB4bGFiKCJzaXRlIHBvc2l0aW9uIikKCmBgYAoKIyMjIyAqKiogRmluYWwgcGxvdCAqKioKYGBge3J9Cmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BERi9GaWd1cmVfUzEyLnBkZiIsCiAgICAgICB3aWR0aD0xMiwKICAgICAgIGhlaWdodD0xMCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzEyLnBuZyIsCiAgICAgICB3aWR0aD0xMiwKICAgICAgIGhlaWdodD0xMCkKYGBgCiMjIyAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uCgojIyMgLS0tLUtvYnV2aXJ1cyAvIENhcmRpb3ZpcnVzIHJlc3VsdHMtLS0tCgojIyMjIEZpZ3VyZSBTMTMKCmBgYHtyfQoKa29idV9kZXB0aCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9rb2J1dmlydXMva29idXZpcnVzX1RFX3BvbHlvbWljc19yZWFkZGVwdGhfMjAyNDEwMDcudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKSAlPiUKICBzZWxlY3QoIWV4cHQpICU+JQogIHNlbGVjdCghTnVtYmVyLm9mLnBhaXJlZC5lbmQucmVhZHMuLlFULikKCmNhcmRpb19kZXB0aCA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9jYXJkaW92aXJ1cy9jYXJkaW92aXJ1c19kZW5vdm9fYm93dGllMl9yZWFkX2RlcHRoX3Blcl9zYW1wbGVfZGVkdXAudHN2IiwKICAgIHNlcCA9ICIsIiwKICAgIGhlYWRlciA9IFRSVUUKICApCgpjYXJkaW9fZGVwdGhfcG9seSA8LSAKICByZWFkLnRhYmxlKAogICAgImRhdGFfY2FyZGlvdmlydXMvY2FyZGlvdmlydXNfZGVub3ZvX2Jvd3RpZTJfcmVhZGRlcHRoX3Blcl9zYW1wbGVfZGVkdXBfcG9seW9taWNzLnRzdiIsCiAgICBzZXAgPSAiLCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKSB8PgogIHNlbGVjdCgtY29udGlnX25hbWUpIHw+CiAgZmlsdGVyKEJhY2tncm91bmQgJWluJSBjKCJTMTgiLCAiUzE5IiwgIlM0MyIpKSB8PgogIHNlbGVjdCgtQmFja2dyb3VuZCkgfD4KICBzZXBhcmF0ZShTYW1wbGVfaWQsIGludG8gPSBjKE5BLCBOQSwgIkJhY2tncm91bmQiKSwgc2VwID0gIi0iLCByZW1vdmUgPSBGQUxTRSkKCmRlcHRoX2JvdGggPC0gcmJpbmQoa29idV9kZXB0aCwgY2FyZGlvX2RlcHRoLCBjYXJkaW9fZGVwdGhfcG9seSkgfD4KICBtdXRhdGUoVmlyYWwubG9hZCA9IGlmZWxzZShpcy5uYShWaXJhbC5sb2FkKSwgMCwgVmlyYWwubG9hZCkpCgpkZXB0aF9ib3RoJHR5cGUgPC0gZGVwdGhfYm90aCR0eXBlIHw+CiAgY2FzZV9tYXRjaCgiZGVkdXBfVEUiIH4gImRlZHVwIiwKICAgICAgICAgICAgICJkZWR1cF9wb2x5b21pY3MiIH4gImRlZHVwIiwKICAgICAgICAgICAgIC5kZWZhdWx0ID0gZGVwdGhfYm90aCR0eXBlKQoKZGVwdGhfYm90aCRTYW1wbGVfaWQgPC0gZGVwdGhfYm90aCRTYW1wbGVfaWQgfD4KICBjYXNlX21hdGNoKCJSTkEtTXNwLXAyIiB+ICJNMSIsCiAgICAgICAgICAgICAiUk5BLU1zcC1wOCIgfiAiTTIiLAogICAgICAgICAgICAgIlJOQS1Nc3AtcDYiIH4gIk0zIiwKICAgICAgICAgICAgIC5kZWZhdWx0ID0gZGVwdGhfYm90aCRTYW1wbGVfaWQKICAgICAgICAgICAgICkKCmRlcHRoX2JvdGgkdmlydXMgPC0gZGVwdGhfYm90aCR2aXJ1cyB8PgogIGNhc2VfbWF0Y2goImNhcmRpb3ZpcnVzIiB+ICJDYXJkaW92aXJ1cyIsCiAgICAgICAgICAgICAiazk3XzE5OTcxIiB+ICJLb2J1dmlydXMiLAogICAgICAgICAgICAgLmRlZmF1bHQgPSBkZXB0aF9ib3RoJHZpcnVzCiAgICAgICAgICAgICApCgpjb2xzMiA8LSBjKCIjQkI1NTY2IiwgIiMwMDQ0ODgiKQoKY292ZXJhZ2VfbGFiZWxzIDwtIGMoCiAgIms5N18xOTk3MSIgPSAiS29idXZpcnVzIiwKICAiY2FyZGlvdmlydXMiID0gIkNhcmRpb3ZpcnVzIiwKICAicDIiID0gIk0xIiwKICAicDgiID0gIk0yIgopCgpgYGAKCiMjIyMgKioqIEZpbmFsIHBsb3QgKioqCmBgYHtyfQoKZGVwdGhfYm90aCRWaXJhbC5sb2FkIDwtIGZhY3RvcihkZXB0aF9ib3RoJFZpcmFsLmxvYWQsIGxhYmVscyA9IGMoIlNob3RndW4iLAogICAgIjEwXnsyfSIsIAogICAgIjEwXnszfSIsIAogICAgIjEwXns1fSIKICAgICkpCgoKIyBkZXB0aF9ib3RoIHw+CiMgICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgojICAgZmlsdGVyKHR5cGUgPT0gImRlZHVwIikgfD4KIyAgIGZpbHRlcihtYXBwZXIgPT0gImJvd3RpZTIiKSB8PgojICAgZmlsdGVyKFZpcmFsLmxvYWQgIT0gIk5BIikgfD4KIyAgIGdncGxvdChhZXMoCiMgICAgIHggPSBWaXJhbC5sb2FkLAojICAgICB5ID0gKG1lYW5fZGVwdGgpLAojICAgICBjb2xvdXIgPSBCYWNrZ3JvdW5kCiMgICApKSArCiMgICBnZW9tX3BvaW50KCkgKwojICB0aGVtZV9mZXcoKSArCiMgICB0aGVtZSgKIyAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiMgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAojICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiMgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgCiMgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiMgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKIyAgICkgKyAgCiMgICBmYWNldF9ncmlkKEJhY2tncm91bmQgfiB2aXJ1cywgbGFiZWxsZXIgPSBhc19sYWJlbGxlcihjb3ZlcmFnZV9sYWJlbHMpKSArCiMgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczIpICsKIyAgIHlsYWIoIk1lYW4gcmVhZCBkZXB0aCIpICsKIyAgICAgeGxhYigiU3Bpa2UtaW4gdmlyYWwgbG9hZCAoZ2MvbWwpIikgKwojICAgIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKSArIAojICAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6OmxhYmVsX21hdGgoKSkpCgojIHJlcGxvdHRpbmcgUzEzIGluIHNpbWlsYXIgd2F5IHRvIFMxNApkZXB0aF9ib3RoICU+JQogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwIikgfD4KICBmaWx0ZXIobWFwcGVyID09ICJib3d0aWUyIikgfD4KICAjIGZpbHRlcihWaXJhbC5sb2FkICE9ICJOQSIpIHw+CiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlX2lkLCB5ID0gbWVhbl9kZXB0aCwgY29sb3IgPSBCYWNrZ3JvdW5kKSkgKwogIGdlb21fcG9pbnQoKSArCiAgeWxhYigiTWVhbiByZWFkIGRlcHRoIikgKwogIHhsYWIoIlNhbXBsZSBJRCIpICsKICBmYWNldF9ncmlkKHZpcnVzIH4gVmlyYWwubG9hZCwKICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLAogICAgICAgICAgICAgbGFiZWwgPSBsYWJlbF9wYXJzZWQpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIk0xIiwgIk0yIikpICsKIHRoZW1lX2ZldygpICsKICB0aGVtZSgKICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoPTAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImxpZ2h0Z3JheSIpCiAgKSsKICBzY2FsZV95X2xvZzEwKGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6OmxhYmVsX21hdGgoKSkpCgoKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV9TMTNfdjIucGRmIiwKICAgICAgIHdpZHRoPTgsCiAgICAgICBoZWlnaHQ9NCkKCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzEzX3YyLnBuZyIsCiAgICAgICB3aWR0aD04LAogICAgICAgaGVpZ2h0PTQpCgpgYGAKCiMjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIyBGaWd1cmUgUzE0CgpgYGB7cn0KCmtvYnVfcGVyX3NpdGUgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfa29idXZpcnVzL2tvYnV2aXJ1c19URV9wb2x5b21pY3NfcmVhZGRlcHRoX3BlcnNpdGVfMjAyNDEwMDcudHN2IiwKICAgIHNlcCA9ICJcdCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKSAlPiUKICBzZWxlY3QodmlydXMsCiAgICAgICAgIHNlZywKICAgICAgICAgc2l0ZSwKICAgICAgICAgY292ZXJhZ2UsCiAgICAgICAgIG5fc2l0ZXMsCiAgICAgICAgIFNhbXBsZV9pZCwKICAgICAgICAgQmFja2dyb3VuZCwKICAgICAgICAgVmlyYWwubG9hZCwKICAgICAgICAgbWFwcGVyLAogICAgICAgICB0eXBlKQoKa29idV9wZXJfc2l0ZSRWaXJhbC5sb2FkIDwtIAogIGtvYnVfcGVyX3NpdGUkVmlyYWwubG9hZCAlPiUKICByZXBsYWNlX25hKC4sIDApCgprb2J1X3Blcl9zaXRlJFNhbXBsZV9pZCA8LSBrb2J1X3Blcl9zaXRlJFNhbXBsZV9pZCAlPiUKICBjYXNlX21hdGNoKCJSTkEtTXNwLXAyIiB+ICJNMSIsCiAgICAgICAgICAgICAiUk5BLU1zcC1wOCIgfiAiTTIiLAogICAgICAgICAgICAgLmRlZmF1bHQgPSBrb2J1X3Blcl9zaXRlJFNhbXBsZV9pZCkKCmtvYnVfcGVyX3NpdGUkQmFja2dyb3VuZCA8LSBrb2J1X3Blcl9zaXRlJEJhY2tncm91bmQgJT4lCiAgY2FzZV9tYXRjaCgicDIiIH4gIk0xIiwKICAgICAgICAgICAgICJwOCIgfiAiTTIiLAogICAgICAgICAgICAgLmRlZmF1bHQgPSBrb2J1X3Blcl9zaXRlJEJhY2tncm91bmQpCgpjYXJkaW9fcGVyX3NpdGUgPC0KICByZWFkLnRhYmxlKAogICAgImRhdGFfY2FyZGlvdmlydXMvY2FyZGlvdmlydXNfZGVub3ZvX2Jvd3RpZTJfcmVhZF9kZXB0aF9wZXJfc2l0ZV9hbmRfc2FtcGxlX2RlZHVwLnRzdiIsCiAgICBzZXAgPSAiLCIsCiAgICBoZWFkZXIgPSBUUlVFCiAgKQoKY2FyZGlvX3BvbHlvbWljc19wZXJfc2l0ZSA8LQogIHJlYWQudGFibGUoCiAgICAiZGF0YV9jYXJkaW92aXJ1cy9jYXJkaW92aXJ1c19kZW5vdm9fYm93dGllMl9yZWFkZGVwdGhfcGVyX3NpdGVfc2FtcGxlX2RlZHVwX3BvbHlvbWljcy50c3YiLAogICAgc2VwID0gIiwiLAogICAgaGVhZGVyID0gVFJVRQogICkgJT4lCiAgc2VsZWN0KCFjb250aWdfbmFtZSkKCiNWaWV3KGNhcmRpb19wb2x5b21pY3NfcGVyX3NpdGUpCgpjYXJkaW9fVEVfcG9seW9taWNzIDwtCiAgZnVsbF9qb2luKAogICAgY2FyZGlvX3Blcl9zaXRlLAogICAgY2FyZGlvX3BvbHlvbWljc19wZXJfc2l0ZSwKICAgIGJ5ID0gYygKICAgICAgInZpcnVzIiwKICAgICAgInNlZyIsCiAgICAgICJzaXRlIiwKICAgICAgImNvdmVyYWdlIiwKICAgICAgIm5fc2l0ZXMiLAogICAgICAiU2FtcGxlX2lkIiwKICAgICAgIkJhY2tncm91bmQiLAogICAgICAiVmlyYWwubG9hZCIsCiAgICAgICJtYXBwZXIiLAogICAgICAidHlwZSIKICAgICkKICApCgpjYXJkaW9fVEVfcG9seW9taWNzJFZpcmFsLmxvYWQgPC0gY2FyZGlvX1RFX3BvbHlvbWljcyRWaXJhbC5sb2FkICU+JQogIHJlcGxhY2VfbmEoLiwgMCkKCmRyb3BzIDwtCiAgYygKICAgICJSTkEtTXNwLXAxIiwKICAgICJSTkEtTXNwLXAzIiwKICAgICJSTkEtTXNwLXA0IiwKICAgICJSTkEtTXNwLXA1IiwKICAgICJSTkEtTXNwLXA2IiwKICAgICJSTkEtTXNwLXA3IiwKICAgICJSTkEtTXNwLXA5IgogICkKCmNhcmRpb19URV9wb2x5b21pY3MgPC0gY2FyZGlvX1RFX3BvbHlvbWljcyAlPiUKICBmaWx0ZXIoIVNhbXBsZV9pZCAlaW4lIGRyb3BzKQoKY2FyZGlvX1RFX3BvbHlvbWljcyRTYW1wbGVfaWQgPC0gY2FyZGlvX1RFX3BvbHlvbWljcyRTYW1wbGVfaWQgJT4lCiAgY2FzZV9tYXRjaCgiUk5BLU1zcC1wMiIgfiAiTTEiLAogICAgICAgICAgICAgIlJOQS1Nc3AtcDgiIH4gIk0yIiwKICAgICAgICAgICAgIC5kZWZhdWx0ID0gY2FyZGlvX1RFX3BvbHlvbWljcyRTYW1wbGVfaWQpCgpjYXJkaW9fVEVfcG9seW9taWNzJEJhY2tncm91bmQgPC0gY2FyZGlvX1RFX3BvbHlvbWljcyRCYWNrZ3JvdW5kICU+JQogIGNhc2VfbWF0Y2goIlMxOCIgfiAiTTEiLAogICAgICAgICAgICAgIlM0MyIgfiAiTTIiLAogICAgICAgICAgICAgInAyIiB+ICJNMSIsCiAgICAgICAgICAgICAicDgiIH4gIk0yIiwKICAgICAgICAgICAgIC5kZWZhdWx0ID0gY2FyZGlvX1RFX3BvbHlvbWljcyRCYWNrZ3JvdW5kKQoKcGVyc2l0ZV9ib3RoIDwtIHJiaW5kKGtvYnVfcGVyX3NpdGUsIGNhcmRpb19URV9wb2x5b21pY3MpCgpwZXJzaXRlX2JvdGgkdHlwZSA8LSBwZXJzaXRlX2JvdGgkdHlwZSAlPiUKICBjYXNlX21hdGNoKCJkZWR1cF9URSIgfiAiZGVkdXAiLAogICAgICAgICAgICAgImRlZHVwX3BvbHlvbWljcyIgfiAiZGVkdXAiLAogICAgICAgICAgICAgLmRlZmF1bHQgPSBwZXJzaXRlX2JvdGgkdHlwZSkKCiNURSBkYXRhIG9ubHkgLSBjb21wYXJlIGNvdmVyYWdlIGJldHdlZW4gYmFja2dyb3VuZHMvdmlyYWwgbG9hZHMKCmNvbHMyIDwtIGMoIiNCQjU1NjYiLCAiIzAwNDQ4OCIpCgpjb3ZlcmFnZV9sYWJlbHMgPC0gYygKICAiMTAwIiA9ICIxMF57Mn0iLAogICIxMDAwIiA9ICIxMF57M30iLAogICIxMDAwMDAiID0gIjEwXns1fSIsCiAgIjAiID0gIlNob3RndW4iLAogICJLb2J1dmlydXMiID0gIktvYnV2aXJ1cyIsCiAgIkNhcmRpb3ZpcnVzIiA9ICJDYXJkaW92aXJ1cyIKKQoKY292ZXJhZ2VfbGFiZWxzMiA8LSBjKAogICIxMDAiID0gIjEwXnsyfSIsCiAgIjEwMDAiID0gIjEwXnszfSIsCiAgIjEwMDAwMCIgPSAiMTBeezV9IiwKICAiMCIgPSAiU2hvdGd1biIsCiAgIkEiID0gIkEiLAogICJCIiA9ICJCIiwKICAiQyIgPSAiQyIsCiAgIkQiID0gIkQiLAogICJGIiA9ICJGIiwKICAiRyIgPSAiRyIsCiAgIkgiID0gIkgiLAogICJJIiA9ICJJIiwKICAiSiIgPSAiSiIsCiAgIksiID0gIksiLAogICJMIiA9ICJMIiwKICAiTSIgPSAiTSIsCiAgIk4iID0gIk4iLAogICJPIiA9ICJPIiwKICAiUCIgPSAiUCIsCiAgIk1FX1AxIiA9ICJNMSIsCiAgIk1FX1AyIiA9ICJNMiIKKQoKa29idV9jb3ZlcmFnZSA8LSBrb2J1X3Blcl9zaXRlICU+JQogIGZpbHRlcihtYXBwZXIgPT0gImJvd3RpZTIiKSAlPiUKICBmaWx0ZXIodHlwZSA9PSAiZGVkdXAiKSAlPiUKICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSAlPiUKICBncm91cF9ieShTYW1wbGVfaWQsIFZpcmFsLmxvYWQsIEJhY2tncm91bmQpICU+JQogIGZpbHRlcihjb3ZlcmFnZSA+IDApICU+JQogIHN1bW1hcmlzZShnZW5vbWVfY292ZXJhZ2UgPSBuKCkpICU+JQogIG11dGF0ZShwZXJjZW50X2NvdmVyYWdlID0gZ2Vub21lX2NvdmVyYWdlIC8gODQ2NykgJT4lCiAgbXV0YXRlKHZpcnVzID0gIktvYnV2aXJ1cyIpCgpjYXJkaW9fY292ZXJhZ2UgPC0gY2FyZGlvX1RFX3BvbHlvbWljcyAlPiUKICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSAlPiUKICBncm91cF9ieShTYW1wbGVfaWQsIFZpcmFsLmxvYWQsIEJhY2tncm91bmQpICU+JQogIGZpbHRlcihjb3ZlcmFnZSA+IDApICU+JQogIHN1bW1hcmlzZShnZW5vbWVfY292ZXJhZ2UgPSBuKCkpICU+JQogIG11dGF0ZShwZXJjZW50X2NvdmVyYWdlID0gZ2Vub21lX2NvdmVyYWdlIC8gNjk0NSkgJT4lCiAgbXV0YXRlKHZpcnVzID0gIkNhcmRpb3ZpcnVzIikKCmNvdmVyYWdlX2JvdGggPC0gcmJpbmQoa29idV9jb3ZlcmFnZSwgY2FyZGlvX2NvdmVyYWdlKQoKY292ZXJhZ2VfYm90aCRWaXJhbC5sb2FkIDwtIGZhY3Rvcihjb3ZlcmFnZV9ib3RoJFZpcmFsLmxvYWQsIGxhYmVscyA9IGMoIlNob3RndW4iLAogICAgIjEwXnsyfSIsIAogICAgIjEwXnszfSIsIAogICAgIjEwXns1fSIKICAgICkpCgpgYGAKCiMjIyMgKioqIEZpbmFsIHBsb3QgKioqCmBgYHtyfQoKY292ZXJhZ2VfYm90aCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBTYW1wbGVfaWQsIHkgPSBwZXJjZW50X2NvdmVyYWdlLCBjb2xvciA9IEJhY2tncm91bmQpKSArCiAgZ2VvbV9wb2ludCgpICsKICB5bGFiKCJHZW5vbWUgY292ZXJhZ2UiKSArCiAgeGxhYigiU2FtcGxlIElEIikgKwogIGZhY2V0X2dyaWQodmlydXMgfiAoVmlyYWwubG9hZCksCiAgICAgICAgICAgICBzY2FsZXMgPSAiZnJlZV94IiwKICAgICAgICAgICAgIGxhYmVsID0gbGFiZWxfcGFyc2VkKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJNMSIsICJNMiIpKSArCiB0aGVtZV9mZXcoKSArCiAgdGhlbWUoCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aD0wLjEsIGNvbG9yID0gImdyYXk2MCIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGg9MC4xLCBjb2xvciA9ICJsaWdodGdyYXkiKQogICkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAxKSkKCiNQREYKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV9TMTQucGRmIiwgCiAgICAgICB3aWR0aCA9IDgsIAogICAgICAgaGVpZ2h0ID0gNCkKCiNQTkcKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUE5HL0ZpZ3VyZV9TMTQucG5nIiwgCiAgICAgICB3aWR0aCA9IDgsIAogICAgICAgaGVpZ2h0ID0gNCkKCmBgYAoKCgojIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyMgRmlndXJlIFMxNQoKYGBge3IsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgojcGVyIHNpdGUgZ2Vub21lIGNvdmVyYWdlIC0gS29idQoKcGVyc2l0ZV9ib3RoJFZpcmFsLmxvYWQgPC0gZmFjdG9yKHBlcnNpdGVfYm90aCRWaXJhbC5sb2FkLCBsYWJlbHMgPSBjKCJTaG90Z3VuIiwKICAgICIxMF57Mn0iLCAKICAgICIxMF57M30iLCAKICAgICIxMF57NX0iCiAgICApKQoKcGVyc2l0ZV9ib3RoJFZpcmFsLmxvYWQgPC0gZmFjdG9yKHBlcnNpdGVfYm90aCRWaXJhbC5sb2FkLCBsZXZlbHMgPSBjKAogICAgIjEwXnsyfSIsIAogICAgIjEwXnszfSIsIAogICAgIjEwXns1fSIsCiAgICAiU2hvdGd1biIKICAgICkpCgpwZXJzaXRlX2JvdGggfD4KICBmaWx0ZXIodmlydXMgPT0gIms5N18xOTk3MSIpIHw+CiAgZmlsdGVyKG1hcHBlciA9PSAiYm93dGllMiIpIHw+CiAgZmlsdGVyKHR5cGUgPT0gImRlZHVwIikgfD4KICBmaWx0ZXIoQmFja2dyb3VuZCAhPSAicDYiKSB8PgogIGdncGxvdChhZXMoCiAgICB4ID0gc2l0ZSwKICAgIHkgPSAoY292ZXJhZ2UpLAogICAgZmlsbCA9IEJhY2tncm91bmQKICApKSArCiAgZ2VvbV9jb2woKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsgICAKICBmYWNldF93cmFwKFZpcmFsLmxvYWQgfiBTYW1wbGVfaWQsIGxhYmVsbGVyID0gbGFiZWxfcGFyc2VkKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sczIsIGxhYmVscyA9IGMoIk0xIiwgIk0yIikpICsKICB5bGFiKCJDb3ZlcmFnZSIpICsKICB4bGFiKCIiKSArCiAgZ2d0aXRsZSgiS29idXZpcnVzIikgKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlczo6bGFiZWxfbWF0aCgpKSkKCmBgYAoKIyMjIyAqKiogRmluYWwgcGxvdCAqKioKYGBge3J9CiNQREYKZ2dzYXZlKCJmaWd1cmVzL21hbnVzY3JpcHRfZmlndXJlXzIwMjUvUERGL0ZpZ3VyZV9TMTUucGRmIiwKICAgICAgIHdpZHRoPTEyLAogICAgICAgaGVpZ2h0PTcpCgojUE5HCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BuZy9GaWd1cmVfUzE1LnBuZyIsCiAgICAgICB3aWR0aD0xMiwKICAgICAgIGhlaWdodD03KQoKYGBgCgojIyMjIEZpZ3VyZSBTMTYKYGBge3IsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CgojcGVyIHNpdGUgZ2Vub21lIGNvdmVyYWdlIC0gQ2FyZGlvCgpwZXJzaXRlX2JvdGggfD4KICBmaWx0ZXIodmlydXMgPT0gImNhcmRpb3ZpcnVzIikgfD4KICBmaWx0ZXIobWFwcGVyID09ICJib3d0aWUyIikgfD4KICBmaWx0ZXIodHlwZSA9PSAiZGVkdXAiKSB8PgogIGZpbHRlcihCYWNrZ3JvdW5kICE9ICJwNiIpIHw+CiAgZ2dwbG90KGFlcygKICAgIHggPSBzaXRlLAogICAgeSA9IGNvdmVyYWdlLAogICAgZmlsbCA9IEJhY2tncm91bmQKICApKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfd3JhcChWaXJhbC5sb2FkIH4gU2FtcGxlX2lkLCBsYWJlbGxlciA9IGxhYmVsX3BhcnNlZCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbHMyLCBsYWJlbHMgPSBjKCJNMSIsICJNMiIpKSArCiAgdGhlbWVfZmV3KCkgKwogIHRoZW1lKAogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAiZ3JheTYwIiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMSwgY29sb3IgPSAibGlnaHRncmF5IikKICApICsKICB5bGFiKCJDb3ZlcmFnZSIpICsKICB4bGFiKCIiKSArCiAgZ2d0aXRsZSgiQ2FyZGlvdmlydXMiKSArCiAgc2NhbGVfeV9sb2cxMChsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVzOjpsYWJlbF9tYXRoKCkpKQpgYGAKCiMjIyMgKioqIEZpbmFsIHBsb3QgKioqCmBgYHtyfQoKI1BERgpnZ3NhdmUoImZpZ3VyZXMvbWFudXNjcmlwdF9maWd1cmVfMjAyNS9QREYvRmlndXJlX1MxNi5wZGYiLAogICAgICAgd2lkdGg9MTIsCiAgICAgICBoZWlnaHQ9NykKCgojUE5HCmdnc2F2ZSgiZmlndXJlcy9tYW51c2NyaXB0X2ZpZ3VyZV8yMDI1L1BORy9GaWd1cmVfUzE2LnBuZyIsCiAgICAgICB3aWR0aD0xMiwKICAgICAgIGhlaWdodD03KQpgYGAKCg==